/*

   ____                               ____      ___ ____       ____  ____      ___
  6MMMMb                              `MM(      )M' `MM'      6MMMMb\`MM(      )M'
 8P    Y8                              `MM.     d'   MM      6M'    ` `MM.     d'
6M      Mb __ ____     ____  ___  __    `MM.   d'    MM      MM        `MM.   d'
MM      MM `M6MMMMb   6MMMMb `MM 6MMb    `MM. d'     MM      YM.        `MM. d'
MM      MM  MM'  `Mb 6M'  `Mb MMM9 `Mb    `MMd       MM       YMMMMb     `MMd
MM      MM  MM    MM MM    MM MM'   MM     dMM.      MM           `Mb     dMM.
MM      MM  MM    MM MMMMMMMM MM    MM    d'`MM.     MM            MM    d'`MM.
YM      M9  MM    MM MM       MM    MM   d'  `MM.    MM            MM   d'  `MM.
 8b    d8   MM.  ,M9 YM    d9 MM    MM  d'    `MM.   MM    / L    ,M9  d'    `MM.
  YMMMM9    MMYMMM9   YMMMM9 _MM_  _MM_M(_    _)MM_ _MMMMMMM MYMMMM9 _M(_    _)MM_
            MM
            MM
           _MM_

  Copyright (c) 2018, Kenneth Troldal Balslev

  All rights reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are met:
  - Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.
  - Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.
  - Neither the name of the author nor the
    names of any contributors may be used to endorse or promote products
    derived from this software without specific prior written permission.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

 */

// ===== External Includes ===== //
#ifdef ENABLE_NOWIDE
#    include <nowide/fstream.hpp>
#endif
#if defined(_WIN32)
#    include <random>
#endif
#include <pugixml.hpp>

// ===== OpenXLSX Includes ===== //
#include "XLContentTypes.hpp"
#include "XLDocument.hpp"
#include "XLSheet.hpp"
#include "utilities/XLUtilities.hpp"

#include <algorithm>

using namespace OpenXLSX;

namespace
{
    constexpr int           templateSize       = 7714;
    constexpr unsigned char templateData[7714] = {
        0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x06, 0x00, 0x08, 0x00, 0x00, 0x00, 0x21, 0x00, 0xb5, 0x55, 0x30, 0x23, 0xf4, 0x00, 0x00, 0x00,
        0x4c, 0x02, 0x00, 0x00, 0x0b, 0x00, 0x08, 0x02, 0x5f, 0x72, 0x65, 0x6c, 0x73, 0x2f, 0x2e, 0x72, 0x65, 0x6c, 0x73, 0x20, 0xa2, 0x04,
        0x02, 0x28, 0xa0, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x92, 0x4d, 0x4f, 0xc3, 0x30, 0x0c, 0x86, 0xef, 0x48, 0xfc,
        0x87, 0xc8, 0xf7, 0xd5, 0xdd, 0x90, 0x10, 0x42, 0x4b, 0x77, 0x41, 0x48, 0xbb, 0x21, 0x54, 0x7e, 0x80, 0x49, 0xdc, 0x0f, 0xb5, 0x8d,
        0xa3, 0x24, 0x1b, 0xdd, 0xbf, 0x27, 0x1c, 0x10, 0x54, 0x1a, 0x83, 0x03, 0x47, 0x7f, 0xbd, 0x7e, 0xfc, 0xca, 0xdb, 0xdd, 0x3c, 0x8d,
        0xea, 0xc8, 0x21, 0xf6, 0xe2, 0x34, 0xac, 0x8b, 0x12, 0x14, 0x3b, 0x23, 0xb6, 0x77, 0xad, 0x86, 0x97, 0xfa, 0x71, 0x75, 0x07, 0x2a,
        0x26, 0x72, 0x96, 0x46, 0x71, 0xac, 0xe1, 0xc4, 0x11, 0x76, 0xd5, 0xf5, 0xd5, 0xf6, 0x99, 0x47, 0x4a, 0x79, 0x28, 0x76, 0xbd, 0x8f,
        0x2a, 0xab, 0xb8, 0xa8, 0xa1, 0x4b, 0xc9, 0xdf, 0x23, 0x46, 0xd3, 0xf1, 0x44, 0xb1, 0x10, 0xcf, 0x2e, 0x57, 0x1a, 0x09, 0x13, 0xa5,
        0x1c, 0x86, 0x16, 0x3d, 0x99, 0x81, 0x5a, 0xc6, 0x4d, 0x59, 0xde, 0x62, 0xf8, 0xae, 0x01, 0xd5, 0x42, 0x53, 0xed, 0xad, 0x86, 0xb0,
        0xb7, 0x37, 0xa0, 0xea, 0x93, 0xcf, 0x9b, 0x7f, 0xd7, 0x96, 0xa6, 0xe9, 0x0d, 0x3f, 0x88, 0x39, 0x4c, 0xec, 0xd2, 0x99, 0x15, 0xc8,
        0x73, 0x62, 0x67, 0xd9, 0xae, 0x7c, 0xc8, 0x6c, 0x21, 0xf5, 0xf9, 0x1a, 0x55, 0x53, 0x68, 0x39, 0x69, 0xb0, 0x62, 0x9e, 0x72, 0x3a,
        0x22, 0x79, 0x5f, 0x64, 0x6c, 0xc0, 0xf3, 0x44, 0x9b, 0xbf, 0x13, 0xfd, 0x7c, 0x2d, 0x4e, 0x9c, 0xc8, 0x52, 0x22, 0x34, 0x12, 0xf8,
        0x32, 0xcf, 0x47, 0xc7, 0x25, 0xa0, 0xf5, 0x7f, 0x5a, 0xb4, 0x34, 0xf1, 0xcb, 0x9d, 0x79, 0xc4, 0x37, 0x09, 0xc3, 0xab, 0xc8, 0xf0,
        0xc9, 0x82, 0x8b, 0x1f, 0xa8, 0xde, 0x01, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x06, 0x00, 0x08,
        0x00, 0x00, 0x00, 0x21, 0x00, 0x47, 0x88, 0xbc, 0xe2, 0x5d, 0x03, 0x00, 0x00, 0x35, 0x08, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x78,
        0x6c, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x62, 0x6f, 0x6f, 0x6b, 0x2e, 0x78, 0x6d, 0x6c, 0xac, 0x55, 0x6d, 0x6f, 0xa3, 0x38, 0x10, 0xfe,
        0x7e, 0xd2, 0xfd, 0x07, 0xc4, 0x77, 0x8a, 0x4d, 0xcc, 0x4b, 0x50, 0xe9, 0x2a, 0x90, 0xa0, 0xab, 0xb4, 0x5d, 0x55, 0x6d, 0xb6, 0xfb,
        0xf1, 0xe4, 0x80, 0x29, 0x56, 0x01, 0x73, 0xc6, 0x34, 0xa9, 0xaa, 0xfd, 0xef, 0x3b, 0x76, 0x42, 0xda, 0x6e, 0x57, 0xa7, 0x5c, 0xf7,
        0xaa, 0xd4, 0xc6, 0x9e, 0xe1, 0xf1, 0x33, 0x33, 0xcf, 0x98, 0xf3, 0x4f, 0xbb, 0xb6, 0xb1, 0x1e, 0x99, 0x1c, 0xb8, 0xe8, 0x12, 0x1b,
        0x9f, 0x21, 0xdb, 0x62, 0x5d, 0x21, 0x4a, 0xde, 0xdd, 0x27, 0xf6, 0xd7, 0x75, 0xee, 0x44, 0xb6, 0x35, 0x28, 0xda, 0x95, 0xb4, 0x11,
        0x1d, 0x4b, 0xec, 0x27, 0x36, 0xd8, 0x9f, 0x2e, 0xfe, 0xfc, 0xe3, 0x7c, 0x2b, 0xe4, 0xc3, 0x46, 0x88, 0x07, 0x0b, 0x00, 0xba, 0x21,
        0xb1, 0x6b, 0xa5, 0xfa, 0xd8, 0x75, 0x87, 0xa2, 0x66, 0x2d, 0x1d, 0xce, 0x44, 0xcf, 0x3a, 0xb0, 0x54, 0x42, 0xb6, 0x54, 0xc1, 0x52,
        0xde, 0xbb, 0x43, 0x2f, 0x19, 0x2d, 0x87, 0x9a, 0x31, 0xd5, 0x36, 0xae, 0x87, 0x50, 0xe0, 0xb6, 0x94, 0x77, 0xf6, 0x1e, 0x21, 0x96,
        0xa7, 0x60, 0x88, 0xaa, 0xe2, 0x05, 0x5b, 0x8a, 0x62, 0x6c, 0x59, 0xa7, 0xf6, 0x20, 0x92, 0x35, 0x54, 0x01, 0xfd, 0xa1, 0xe6, 0xfd,
        0x30, 0xa1, 0xb5, 0xc5, 0x29, 0x70, 0x2d, 0x95, 0x0f, 0x63, 0xef, 0x14, 0xa2, 0xed, 0x01, 0x62, 0xc3, 0x1b, 0xae, 0x9e, 0x0c, 0xa8,
        0x6d, 0xb5, 0x45, 0x7c, 0x79, 0xdf, 0x09, 0x49, 0x37, 0x0d, 0x84, 0xbd, 0xc3, 0xbe, 0xb5, 0x93, 0xf0, 0x0b, 0xe0, 0x1f, 0x23, 0x18,
        0xbc, 0xe9, 0x24, 0x30, 0xbd, 0x3b, 0xaa, 0xe5, 0x85, 0x14, 0x83, 0xa8, 0xd4, 0x19, 0x40, 0xbb, 0x7b, 0xd2, 0xef, 0xe2, 0xc7, 0xc8,
        0xc5, 0xf8, 0x4d, 0x0a, 0x76, 0xef, 0x73, 0x70, 0x1a, 0x12, 0x71, 0x25, 0x7b, 0xe4, 0xba, 0x86, 0x47, 0x56, 0x32, 0xf8, 0x20, 0xab,
        0xe0, 0x88, 0x15, 0xbc, 0x80, 0x61, 0xf4, 0xdb, 0x68, 0x18, 0xa4, 0x65, 0xb4, 0x12, 0x43, 0xf2, 0x3e, 0x88, 0xe6, 0x1f, 0xb9, 0x79,
        0xf6, 0xc5, 0x79, 0xc5, 0x1b, 0x76, 0xb7, 0x97, 0xae, 0x45, 0xfb, 0xfe, 0x0b, 0x6d, 0x75, 0xa5, 0x1a, 0xdb, 0x6a, 0xe8, 0xa0, 0x56,
        0x25, 0x57, 0xac, 0x4c, 0xec, 0x10, 0x96, 0x62, 0xcb, 0xde, 0x6c, 0xc8, 0xb1, 0x4f, 0x47, 0xde, 0x80, 0x15, 0xa3, 0x08, 0x7b, 0xb6,
        0x7b, 0x71, 0x94, 0xf3, 0xb5, 0xb4, 0x4a, 0x56, 0xd1, 0xb1, 0x51, 0x6b, 0x10, 0xf2, 0x04, 0x0f, 0x8e, 0x41, 0x30, 0xf7, 0x7c, 0xed,
        0x09, 0xc2, 0x58, 0x34, 0x8a, 0xc9, 0x8e, 0x2a, 0x96, 0x89, 0x4e, 0x81, 0x0e, 0x0f, 0x71, 0xfd, 0xae, 0xe6, 0x0c, 0x76, 0x56, 0x0b,
        0x50, 0xb8, 0x75, 0xc3, 0xfe, 0x19, 0xb9, 0x64, 0xd0, 0x58, 0xa0, 0x2f, 0x88, 0x15, 0x46, 0x5a, 0xc4, 0x74, 0x33, 0x5c, 0x53, 0x55,
        0x5b, 0xa3, 0x6c, 0x12, 0xdb, 0xfd, 0x3a, 0x40, 0xf0, 0xee, 0x5a, 0x8a, 0x06, 0xba, 0xd3, 0x5d, 0xb2, 0x47, 0xd6, 0x88, 0xde, 0xf4,
        0xc5, 0x86, 0x77, 0x5e, 0xe1, 0xbe, 0x52, 0x28, 0x7d, 0xdf, 0x0e, 0xff, 0x41, 0xa3, 0xb4, 0xd0, 0x81, 0xbb, 0x10, 0xf9, 0x9e, 0xdd,
        0xfe, 0xf9, 0xe7, 0x2c, 0x00, 0x49, 0x19, 0x4f, 0x3a, 0xbc, 0x56, 0xd2, 0x82, 0xe7, 0xcb, 0xe5, 0x67, 0xa8, 0xc5, 0x2d, 0x7d, 0x84,
        0xca, 0x40, 0xfd, 0xcb, 0x43, 0xe3, 0x5e, 0x42, 0xea, 0xa3, 0xbf, 0x9f, 0x17, 0xd9, 0x6c, 0xb6, 0x08, 0xf2, 0xd4, 0xc1, 0x01, 0x9a,
        0x39, 0x5e, 0x40, 0xb0, 0xb3, 0x20, 0x28, 0x77, 0xd2, 0x30, 0x0b, 0x73, 0x2f, 0x45, 0xab, 0x60, 0x1e, 0x7d, 0x87, 0x28, 0x64, 0x10,
        0x17, 0x82, 0x8e, 0xaa, 0x3e, 0x54, 0x5b, 0x63, 0x26, 0x36, 0x21, 0xbf, 0x30, 0x5d, 0xd1, 0xdd, 0x64, 0xc1, 0x28, 0x1e, 0x79, 0xf9,
        0x72, 0xfe, 0x33, 0x3a, 0xfc, 0x39, 0x7a, 0xfe, 0x69, 0x98, 0x6c, 0xdf, 0x75, 0xa4, 0xfa, 0x5e, 0xbb, 0xe3, 0x6c, 0x3b, 0xbc, 0xe8,
        0x42, 0x2f, 0xad, 0xdd, 0x37, 0xde, 0x95, 0x62, 0x9b, 0xd8, 0x5e, 0x18, 0x41, 0x34, 0x4f, 0xd3, 0x12, 0xfb, 0x01, 0x2c, 0xb7, 0xc6,
        0xf8, 0x8d, 0x97, 0xaa, 0x06, 0x8f, 0x08, 0x91, 0xe3, 0xde, 0x5f, 0x8c, 0xdf, 0xd7, 0xc0, 0x18, 0x87, 0x44, 0x6f, 0x82, 0xfe, 0x35,
        0xb3, 0xc4, 0x7e, 0xce, 0x73, 0x32, 0x4f, 0x23, 0xbc, 0x70, 0xb0, 0x17, 0x2e, 0x9c, 0x94, 0x90, 0x0c, 0x12, 0x40, 0x52, 0x27, 0xcf,
        0x51, 0x3e, 0x5b, 0xe5, 0x51, 0x9e, 0xe5, 0x73, 0xc3, 0xc8, 0x7d, 0x45, 0xc9, 0xdc, 0xa0, 0x40, 0xcd, 0xcc, 0x56, 0x67, 0x54, 0x7f,
        0xab, 0x6f, 0x55, 0x0c, 0x57, 0xb5, 0x9e, 0x75, 0x76, 0xe1, 0x59, 0xc6, 0xfa, 0x0c, 0x79, 0x59, 0x62, 0x53, 0xbd, 0xe9, 0xb5, 0x82,
        0x36, 0x05, 0xa8, 0x5c, 0x4f, 0xc6, 0x31, 0xc2, 0xc8, 0x9b, 0x6b, 0x0f, 0xb6, 0x53, 0x9f, 0x07, 0x65, 0x66, 0x10, 0x18, 0x07, 0x7a,
        0x98, 0xa0, 0x45, 0x88, 0xe6, 0xc4, 0x41, 0xab, 0x99, 0xef, 0x90, 0x68, 0xee, 0x39, 0x11, 0x99, 0x79, 0x4e, 0x46, 0x96, 0xde, 0xca,
        0x0f, 0x57, 0xcb, 0x55, 0xea, 0xeb, 0xfa, 0xe8, 0x2f, 0x40, 0xfc, 0x7f, 0xdc, 0x83, 0x46, 0xe7, 0xf1, 0xf4, 0x69, 0xd1, 0x2c, 0x6b,
        0x2a, 0xd5, 0x5a, 0xd2, 0xe2, 0x01, 0x3e, 0x48, 0x37, 0xac, 0x4a, 0xe9, 0x00, 0x4a, 0xda, 0x07, 0x04, 0x7c, 0x5f, 0x93, 0x4d, 0xfd,
        0x28, 0x45, 0x33, 0xa0, 0x48, 0x72, 0x9c, 0x3b, 0x04, 0xcf, 0x91, 0x93, 0xa6, 0x01, 0x71, 0xfc, 0x65, 0x3e, 0xf3, 0x43, 0xbc, 0xcc,
        0x56, 0x7e, 0xfe, 0x42, 0x56, 0x87, 0x5f, 0x7d, 0xf0, 0x16, 0x8a, 0x5c, 0xf3, 0x36, 0xa3, 0x6a, 0x84, 0x0e, 0xd5, 0xcd, 0x69, 0xd6,
        0xb1, 0x1e, 0xf3, 0xc3, 0xee, 0x71, 0xb3, 0xda, 0x6f, 0x1c, 0xea, 0xf4, 0xa6, 0xe9, 0xe2, 0x9b, 0xa5, 0xce, 0xfb, 0xe1, 0xed, 0x7f,
        0x73, 0xbc, 0x85, 0xe8, 0x1b, 0x76, 0xa2, 0x73, 0x7e, 0x77, 0xa2, 0x63, 0xf6, 0xe5, 0x6a, 0x7d, 0x65, 0xb4, 0xf1, 0xcb, 0x00, 0x5c,
        0x93, 0x60, 0x3d, 0x1a, 0x59, 0xb8, 0x53, 0x59, 0x2e, 0x7e, 0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, 0x50, 0x4b, 0x03, 0x04, 0x14,
        0x00, 0x06, 0x00, 0x08, 0x00, 0x00, 0x00, 0x21, 0x00, 0xf0, 0x08, 0x58, 0xf4, 0xa5, 0x02, 0x00, 0x00, 0x52, 0x06, 0x00, 0x00, 0x0d,
        0x00, 0x00, 0x00, 0x78, 0x6c, 0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x73, 0x2e, 0x78, 0x6d, 0x6c, 0xa4, 0x55, 0x6d, 0x6b, 0xdb, 0x30,
        0x10, 0xfe, 0x3e, 0xd8, 0x7f, 0x10, 0xfa, 0xee, 0xca, 0x76, 0xe3, 0x2c, 0x09, 0xb6, 0xcb, 0xd2, 0xd4, 0x50, 0xe8, 0xc6, 0xa0, 0x1d,
        0xec, 0xab, 0x62, 0xcb, 0x89, 0xa8, 0x5e, 0x8c, 0x24, 0x67, 0xce, 0xc6, 0xfe, 0xfb, 0x4e, 0x76, 0x5e, 0x1c, 0x3a, 0xb6, 0xd1, 0x7e,
        0x89, 0x4e, 0xe7, 0xd3, 0x73, 0xcf, 0xdd, 0x73, 0x52, 0xd2, 0x9b, 0x4e, 0x0a, 0xb4, 0x63, 0xc6, 0x72, 0xad, 0x32, 0x1c, 0x5d, 0x85,
        0x18, 0x31, 0x55, 0xea, 0x8a, 0xab, 0x4d, 0x86, 0xbf, 0x3e, 0x15, 0xc1, 0x0c, 0x23, 0xeb, 0xa8, 0xaa, 0xa8, 0xd0, 0x8a, 0x65, 0x78,
        0xcf, 0x2c, 0xbe, 0xc9, 0xdf, 0xbf, 0x4b, 0xad, 0xdb, 0x0b, 0xf6, 0xb8, 0x65, 0xcc, 0x21, 0x80, 0x50, 0x36, 0xc3, 0x5b, 0xe7, 0x9a,
        0x05, 0x21, 0xb6, 0xdc, 0x32, 0x49, 0xed, 0x95, 0x6e, 0x98, 0x82, 0x2f, 0xb5, 0x36, 0x92, 0x3a, 0xd8, 0x9a, 0x0d, 0xb1, 0x8d, 0x61,
        0xb4, 0xb2, 0xfe, 0x90, 0x14, 0x24, 0x0e, 0xc3, 0x29, 0x91, 0x94, 0x2b, 0x3c, 0x20, 0x2c, 0x64, 0xf9, 0x3f, 0x20, 0x92, 0x9a, 0xe7,
        0xb6, 0x09, 0x4a, 0x2d, 0x1b, 0xea, 0xf8, 0x9a, 0x0b, 0xee, 0xf6, 0x3d, 0x16, 0x46, 0xb2, 0x5c, 0xdc, 0x6f, 0x94, 0x36, 0x74, 0x2d,
        0x80, 0x6a, 0x17, 0x4d, 0x68, 0x89, 0xba, 0x68, 0x6a, 0x62, 0xd4, 0x99, 0x63, 0x92, 0xde, 0xfb, 0x22, 0x8f, 0xe4, 0xa5, 0xd1, 0x56,
        0xd7, 0xee, 0x0a, 0x70, 0x89, 0xae, 0x6b, 0x5e, 0xb2, 0x97, 0x74, 0xe7, 0x64, 0x4e, 0x68, 0x79, 0x46, 0x02, 0xe4, 0xd7, 0x21, 0x45,
        0x09, 0x09, 0xe3, 0x8b, 0xda, 0x3b, 0xf3, 0x4a, 0xa4, 0x09, 0x31, 0x6c, 0xc7, 0xbd, 0x7c, 0x38, 0x4f, 0x6b, 0xad, 0x9c, 0x45, 0xa5,
        0x6e, 0x95, 0x03, 0x31, 0x81, 0xa8, 0x6f, 0xc1, 0xe2, 0x59, 0xe9, 0xef, 0xaa, 0xf0, 0x9f, 0xbc, 0x73, 0x88, 0xca, 0x53, 0xfb, 0x03,
        0xed, 0xa8, 0x00, 0x4f, 0x8c, 0x49, 0x9e, 0x96, 0x5a, 0x68, 0x83, 0x1c, 0x48, 0x07, 0x9d, 0x8b, 0xbc, 0x47, 0x51, 0xc9, 0x86, 0x88,
        0x5b, 0x2a, 0xf8, 0xda, 0x70, 0xef, 0xac, 0xa9, 0xe4, 0x62, 0x3f, 0xb8, 0xfb, 0x73, 0xbd, 0xda, 0x87, 0x38, 0xc9, 0xa1, 0xf7, 0x3e,
        0x8a, 0x78, 0x1e, 0x87, 0xc5, 0xc2, 0x21, 0x2e, 0xc4, 0x89, 0x55, 0xec, 0x09, 0x80, 0x23, 0x4f, 0x41, 0x3e, 0xc7, 0x8c, 0x2a, 0x60,
        0x83, 0x0e, 0xf6, 0xd3, 0xbe, 0x81, 0xf4, 0x0a, 0x26, 0x6d, 0x80, 0xe9, 0xe3, 0xfe, 0x11, 0xbd, 0x31, 0x74, 0x1f, 0xc5, 0xc9, 0xe8,
        0x00, 0xe9, 0x13, 0xe6, 0xe9, 0x5a, 0x9b, 0x0a, 0x26, 0xfb, 0xdc, 0x8f, 0xa3, 0x2b, 0x4f, 0x05, 0xab, 0x1d, 0x10, 0x35, 0x7c, 0xb3,
        0xf5, 0xab, 0xd3, 0x0d, 0xfc, 0xae, 0xb5, 0x73, 0xa0, 0x7e, 0x9e, 0x56, 0x9c, 0x6e, 0xb4, 0xa2, 0xc2, 0x97, 0x32, 0x80, 0x9c, 0x0c,
        0x28, 0xa7, 0x64, 0x42, 0x3c, 0xfa, 0xe9, 0xff, 0x56, 0x5f, 0x60, 0x77, 0x35, 0x52, 0xad, 0x2c, 0xa4, 0xbb, 0xaf, 0x32, 0x0c, 0xf7,
        0xc8, 0x37, 0xe1, 0x68, 0x42, 0x21, 0x07, 0x73, 0xc0, 0x1b, 0x36, 0x1e, 0x7f, 0x8c, 0x36, 0x60, 0xbf, 0x19, 0x16, 0x75, 0xf5, 0x25,
        0x3e, 0x20, 0x8e, 0x68, 0x5f, 0x90, 0x3e, 0xa5, 0x47, 0x5e, 0xef, 0x0c, 0x7f, 0xf6, 0xd7, 0x55, 0xc0, 0xe4, 0x1c, 0x20, 0xd0, 0xba,
        0xe5, 0xc2, 0x71, 0xf5, 0x07, 0xc2, 0x80, 0x59, 0x75, 0xe7, 0x16, 0x84, 0x5e, 0x01, 0xe7, 0xaf, 0x5e, 0xdf, 0x9c, 0x53, 0x16, 0xe8,
        0x44, 0xc5, 0x6a, 0xda, 0x0a, 0xf7, 0x74, 0xfa, 0x98, 0xe1, 0xb3, 0xfd, 0x89, 0x55, 0xbc, 0x95, 0xf1, 0x29, 0xea, 0x0b, 0xdf, 0x69,
        0xd7, 0x43, 0x64, 0xf8, 0x6c, 0x3f, 0x78, 0xa5, 0xa2, 0xa9, 0xcf, 0xc1, 0x3a, 0xf7, 0x60, 0x61, 0xbc, 0x60, 0x45, 0xad, 0xe1, 0x19,
        0xfe, 0x79, 0xb7, 0xfc, 0x30, 0x5f, 0xdd, 0x15, 0x71, 0x30, 0x0b, 0x97, 0xb3, 0x60, 0x72, 0xcd, 0x92, 0x60, 0x9e, 0x2c, 0x57, 0x41,
        0x32, 0xb9, 0x5d, 0xae, 0x56, 0xc5, 0x3c, 0x8c, 0xc3, 0xdb, 0x5f, 0xa3, 0x07, 0xe0, 0x0d, 0xd7, 0xbf, 0x7f, 0xaf, 0xf2, 0x14, 0x2e,
        0xd6, 0xc2, 0x0a, 0x78, 0x24, 0xcc, 0xa1, 0xd8, 0x43, 0x89, 0x8f, 0x67, 0x5f, 0x86, 0x47, 0x9b, 0x81, 0x7e, 0x3f, 0xa3, 0x40, 0x7b,
        0xcc, 0x7d, 0x1e, 0x4f, 0xc3, 0x8f, 0x49, 0x14, 0x06, 0xc5, 0x75, 0x18, 0x05, 0x93, 0x29, 0x9d, 0x05, 0xb3, 0xe9, 0x75, 0x12, 0x14,
        0x49, 0x14, 0xaf, 0xa6, 0x93, 0xe5, 0x5d, 0x52, 0x24, 0x23, 0xee, 0xc9, 0x2b, 0x9f, 0x89, 0x90, 0x44, 0xd1, 0xf0, 0xe0, 0x78, 0xf2,
        0xc9, 0xc2, 0x71, 0xc9, 0x04, 0x57, 0x47, 0xad, 0x8e, 0x0a, 0x8d, 0xbd, 0x20, 0x12, 0x6c, 0xff, 0x52, 0x04, 0x39, 0x2a, 0x41, 0xce,
        0x7f, 0x06, 0xf9, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x06, 0x00, 0x08, 0x00, 0x00,
        0x00, 0x21, 0x00, 0xc1, 0x17, 0x10, 0xbe, 0x4e, 0x07, 0x00, 0x00, 0xc6, 0x20, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x78, 0x6c, 0x2f,
        0x74, 0x68, 0x65, 0x6d, 0x65, 0x2f, 0x74, 0x68, 0x65, 0x6d, 0x65, 0x31, 0x2e, 0x78, 0x6d, 0x6c, 0xec, 0x59, 0xcd, 0x8b, 0x1b, 0x37,
        0x14, 0xbf, 0x17, 0xfa, 0x3f, 0x0c, 0x73, 0x77, 0xfc, 0x35, 0xe3, 0x8f, 0x25, 0xde, 0xe0, 0xcf, 0x6c, 0x93, 0xdd, 0x24, 0x64, 0x9d,
        0x94, 0x1c, 0xb5, 0xb6, 0xec, 0x51, 0x56, 0x33, 0x32, 0x92, 0xbc, 0x1b, 0x13, 0x02, 0x25, 0x39, 0xf5, 0x52, 0x28, 0xa4, 0xa5, 0x97,
        0x42, 0x6f, 0x3d, 0x94, 0xd2, 0x40, 0x03, 0x0d, 0xbd, 0xf4, 0x8f, 0x09, 0x24, 0xb4, 0xe9, 0x1f, 0xd1, 0x27, 0xcd, 0xd8, 0x23, 0xad,
        0xe5, 0x24, 0x9b, 0x6c, 0x4a, 0x5a, 0x76, 0x0d, 0x8b, 0x47, 0xfe, 0xbd, 0xa7, 0xa7, 0xf7, 0x9e, 0x7e, 0x7a, 0xf3, 0x74, 0xf1, 0xd2,
        0xbd, 0x98, 0x7a, 0x47, 0x98, 0x0b, 0xc2, 0x92, 0x96, 0x5f, 0xbe, 0x50, 0xf2, 0x3d, 0x9c, 0x8c, 0xd8, 0x98, 0x24, 0xd3, 0x96, 0x7f,
        0x6b, 0x38, 0x28, 0x34, 0x7c, 0x4f, 0x48, 0x94, 0x8c, 0x11, 0x65, 0x09, 0x6e, 0xf9, 0x0b, 0x2c, 0xfc, 0x4b, 0xdb, 0x9f, 0x7e, 0x72,
        0x11, 0x6d, 0xc9, 0x08, 0xc7, 0xd8, 0x03, 0xf9, 0x44, 0x6c, 0xa1, 0x96, 0x1f, 0x49, 0x39, 0xdb, 0x2a, 0x16, 0xc5, 0x08, 0x86, 0x91,
        0xb8, 0xc0, 0x66, 0x38, 0x81, 0xdf, 0x26, 0x8c, 0xc7, 0x48, 0xc2, 0x23, 0x9f, 0x16, 0xc7, 0x1c, 0x1d, 0x83, 0xde, 0x98, 0x16, 0x2b,
        0xa5, 0x52, 0xad, 0x18, 0x23, 0x92, 0xf8, 0x5e, 0x82, 0x62, 0x50, 0x7b, 0x7d, 0x32, 0x21, 0x23, 0xec, 0x0d, 0x95, 0x4a, 0x7f, 0x7b,
        0xa9, 0xbc, 0x4f, 0xe1, 0x31, 0x91, 0x42, 0x0d, 0x8c, 0x28, 0xdf, 0x57, 0xaa, 0xb1, 0x25, 0xa1, 0xb1, 0xe3, 0xc3, 0xb2, 0x42, 0x88,
        0x85, 0xe8, 0x52, 0xee, 0x1d, 0x21, 0xda, 0xf2, 0x61, 0x9e, 0x31, 0x3b, 0x1e, 0xe2, 0x7b, 0xd2, 0xf7, 0x28, 0x12, 0x12, 0x7e, 0x68,
        0xf9, 0x25, 0xfd, 0xe7, 0x17, 0xb7, 0x2f, 0x16, 0xd1, 0x56, 0x26, 0x44, 0xe5, 0x06, 0x59, 0x43, 0x6e, 0xa0, 0xff, 0x32, 0xb9, 0x4c,
        0x60, 0x7c, 0x58, 0xd1, 0x73, 0xf2, 0xe9, 0xc1, 0x6a, 0xd2, 0x20, 0x08, 0x83, 0x5a, 0x7b, 0xa5, 0x5f, 0x03, 0xa8, 0x5c, 0xc7, 0xf5,
        0xeb, 0xfd, 0x5a, 0xbf, 0xb6, 0xd2, 0xa7, 0x01, 0x68, 0x34, 0x82, 0x95, 0xa6, 0xb6, 0xd8, 0x3a, 0xeb, 0x95, 0x6e, 0x90, 0x61, 0x0d,
        0x50, 0xfa, 0xd5, 0xa1, 0xbb, 0x57, 0xef, 0x55, 0xcb, 0x16, 0xde, 0xd0, 0x5f, 0x5d, 0xb3, 0xb9, 0x1d, 0xaa, 0x8f, 0x85, 0xd7, 0xa0,
        0x54, 0x7f, 0xb0, 0x86, 0x1f, 0x0c, 0xba, 0xe0, 0x45, 0x0b, 0xaf, 0x41, 0x29, 0x3e, 0x5c, 0xc3, 0x87, 0x9d, 0x66, 0xa7, 0x67, 0xeb,
        0xd7, 0xa0, 0x14, 0x5f, 0x5b, 0xc3, 0xd7, 0x4b, 0xed, 0x5e, 0x50, 0xb7, 0xf4, 0x6b, 0x50, 0x44, 0x49, 0x72, 0xb8, 0x86, 0x2e, 0x85,
        0xb5, 0x6a, 0x77, 0xb9, 0xda, 0x15, 0x64, 0xc2, 0xe8, 0x8e, 0x13, 0xde, 0x0c, 0x83, 0x41, 0xbd, 0x92, 0x29, 0xcf, 0x51, 0x90, 0x0d,
        0xab, 0xec, 0x52, 0x53, 0x4c, 0x58, 0x22, 0x37, 0xe5, 0x5a, 0x8c, 0xee, 0x32, 0x3e, 0x00, 0x80, 0x02, 0x52, 0x24, 0x49, 0xe2, 0xc9,
        0xc5, 0x0c, 0x4f, 0xd0, 0x08, 0xb2, 0xb8, 0x8b, 0x28, 0x39, 0xe0, 0xc4, 0xdb, 0x25, 0xd3, 0x08, 0x12, 0x6f, 0x86, 0x12, 0x26, 0x60,
        0xb8, 0x54, 0x29, 0x0d, 0x4a, 0x55, 0xf8, 0xaf, 0x3e, 0x81, 0xfe, 0xa6, 0x23, 0x8a, 0xb6, 0x30, 0x32, 0xa4, 0x95, 0x5d, 0x60, 0x89,
        0x58, 0x1b, 0x52, 0xf6, 0x78, 0x62, 0xc4, 0xc9, 0x4c, 0xb6, 0xfc, 0x2b, 0xa0, 0xd5, 0x37, 0x20, 0x2f, 0x9e, 0x3d, 0x7b, 0xfe, 0xf0,
        0xe9, 0xf3, 0x87, 0xbf, 0x3d, 0x7f, 0xf4, 0xe8, 0xf9, 0xc3, 0x5f, 0xb2, 0xb9, 0xb5, 0x2a, 0x4b, 0x6e, 0x07, 0x25, 0x53, 0x53, 0xee,
        0xd5, 0x8f, 0x5f, 0xff, 0xfd, 0xfd, 0x17, 0xde, 0x5f, 0xbf, 0xfe, 0xf0, 0xea, 0xf1, 0x37, 0xe9, 0xd4, 0x27, 0xf1, 0xc2, 0xc4, 0xbf,
        0xfc, 0xf9, 0xcb, 0x97, 0xbf, 0xff, 0xf1, 0x3a, 0xf5, 0xb0, 0xe2, 0xdc, 0x15, 0x2f, 0xbe, 0x7d, 0xf2, 0xf2, 0xe9, 0x93, 0x17, 0xdf,
        0x7d, 0xf5, 0xe7, 0x4f, 0x8f, 0x1d, 0xda, 0xdb, 0x1c, 0x1d, 0x98, 0xf0, 0x21, 0x89, 0xb1, 0xf0, 0xae, 0xe1, 0x63, 0xef, 0x26, 0x8b,
        0x61, 0x81, 0x0e, 0xfb, 0xf1, 0x01, 0x3f, 0x9d, 0xc4, 0x30, 0x42, 0xc4, 0x92, 0x40, 0x11, 0xe8, 0x76, 0xa8, 0xee, 0xcb, 0xc8, 0x02,
        0x5e, 0x5b, 0x20, 0xea, 0xc2, 0x75, 0xb0, 0xed, 0xc2, 0xdb, 0x1c, 0x58, 0xc6, 0x05, 0xbc, 0x3c, 0xbf, 0x6b, 0xd9, 0xba, 0x1f, 0xf1,
        0xb9, 0x24, 0x8e, 0x99, 0xaf, 0x46, 0xb1, 0x05, 0xdc, 0x63, 0x8c, 0x76, 0x18, 0x77, 0x3a, 0xe0, 0xaa, 0x9a, 0xcb, 0xf0, 0xf0, 0x70,
        0x9e, 0x4c, 0xdd, 0x93, 0xf3, 0xb9, 0x89, 0xbb, 0x89, 0xd0, 0x91, 0x6b, 0xee, 0x2e, 0x4a, 0xac, 0x00, 0xf7, 0xe7, 0x33, 0xa0, 0x57,
        0xe2, 0x52, 0xd9, 0x8d, 0xb0, 0x65, 0xe6, 0x0d, 0x8a, 0x12, 0x89, 0xa6, 0x38, 0xc1, 0xd2, 0x53, 0xbf, 0xb1, 0x43, 0x8c, 0x1d, 0xab,
        0xbb, 0x43, 0x88, 0xe5, 0xd7, 0x3d, 0x32, 0xe2, 0x4c, 0xb0, 0x89, 0xf4, 0xee, 0x10, 0xaf, 0x83, 0x88, 0xd3, 0x25, 0x43, 0x72, 0x60,
        0x25, 0x52, 0x2e, 0xb4, 0x43, 0x62, 0x88, 0xcb, 0xc2, 0x65, 0x20, 0x84, 0xda, 0xf2, 0xcd, 0xde, 0x6d, 0xaf, 0xc3, 0xa8, 0x6b, 0xd5,
        0x3d, 0x7c, 0x64, 0x23, 0x61, 0x5b, 0x20, 0xea, 0x30, 0x7e, 0x88, 0xa9, 0xe5, 0xc6, 0xcb, 0x68, 0x2e, 0x51, 0xec, 0x52, 0x39, 0x44,
        0x31, 0x35, 0x1d, 0xbe, 0x8b, 0x64, 0xe4, 0x32, 0x72, 0x7f, 0xc1, 0x47, 0x26, 0xae, 0x2f, 0x24, 0x44, 0x7a, 0x8a, 0x29, 0xf3, 0xfa,
        0x63, 0x2c, 0x84, 0x4b, 0xe6, 0x3a, 0x87, 0xf5, 0x1a, 0x41, 0xbf, 0x0a, 0x0c, 0xe3, 0x0e, 0xfb, 0x1e, 0x5d, 0xc4, 0x36, 0x92, 0x4b,
        0x72, 0xe8, 0xd2, 0xb9, 0x8b, 0x18, 0x33, 0x91, 0x3d, 0x76, 0xd8, 0x8d, 0x50, 0x3c, 0x73, 0xda, 0x4c, 0x92, 0xc8, 0xc4, 0x7e, 0x26,
        0x0e, 0x21, 0x45, 0x91, 0x77, 0x83, 0x49, 0x17, 0x7c, 0x8f, 0xd9, 0x3b, 0x44, 0x3d, 0x43, 0x1c, 0x50, 0xb2, 0x31, 0xdc, 0xb7, 0x09,
        0xb6, 0xc2, 0xfd, 0x66, 0x22, 0xb8, 0x05, 0xe4, 0x6a, 0x9a, 0x94, 0x27, 0x88, 0xfa, 0x65, 0xce, 0x1d, 0xb1, 0xbc, 0x8c, 0x99, 0xbd,
        0x1f, 0x17, 0x74, 0x82, 0xb0, 0x8b, 0x65, 0xda, 0x3c, 0xb6, 0xd8, 0xb5, 0xcd, 0x89, 0x33, 0x3b, 0x3a, 0xf3, 0xa9, 0x95, 0xda, 0xbb,
        0x18, 0x53, 0x74, 0x8c, 0xc6, 0x18, 0x7b, 0xb7, 0x3e, 0x73, 0x58, 0xd0, 0x61, 0x33, 0xcb, 0xe7, 0xb9, 0xd1, 0x57, 0x22, 0x60, 0x95,
        0x1d, 0xec, 0x4a, 0xac, 0x2b, 0xc8, 0xce, 0x55, 0xf5, 0x9c, 0x60, 0x01, 0x65, 0x92, 0xaa, 0x6b, 0xd6, 0x29, 0x72, 0x97, 0x08, 0x2b,
        0x65, 0xf7, 0xf1, 0x94, 0x6d, 0xb0, 0x67, 0x6f, 0x71, 0x82, 0x78, 0x16, 0x28, 0x89, 0x11, 0xdf, 0xa4, 0xf9, 0x1a, 0x44, 0xdd, 0x4a,
        0x5d, 0x38, 0xe5, 0x9c, 0x54, 0x7a, 0x9d, 0x8e, 0x0e, 0x4d, 0xe0, 0x35, 0x02, 0xe5, 0x1f, 0xe4, 0x8b, 0xd3, 0x29, 0xd7, 0x05, 0xe8,
        0x30, 0x92, 0xbb, 0xbf, 0x49, 0xeb, 0x8d, 0x08, 0x59, 0x67, 0x97, 0x7a, 0x16, 0xee, 0x7c, 0x5d, 0x70, 0x2b, 0x7e, 0x6f, 0xb3, 0xc7,
        0x60, 0x5f, 0xde, 0x3d, 0xed, 0xbe, 0x04, 0x19, 0x7c, 0x6a, 0x19, 0x20, 0xf6, 0xb7, 0xf6, 0xcd, 0x10, 0x51, 0x6b, 0x82, 0x3c, 0x61,
        0x86, 0x08, 0x0a, 0x0c, 0x17, 0xdd, 0x82, 0x88, 0x15, 0xfe, 0x5c, 0x44, 0x9d, 0xab, 0x5a, 0x6c, 0xee, 0x94, 0x9b, 0xd8, 0x9b, 0x36,
        0x0f, 0x03, 0x14, 0x46, 0x56, 0xbd, 0x13, 0x93, 0xe4, 0x8d, 0xc5, 0xcf, 0x89, 0xb2, 0x27, 0xfc, 0x77, 0xca, 0x1e, 0x77, 0x01, 0x73,
        0x06, 0x05, 0x8f, 0x5b, 0xf1, 0xfb, 0x94, 0x3a, 0x9b, 0x28, 0x65, 0xe7, 0x44, 0x81, 0xb3, 0x09, 0xf7, 0x1f, 0x2c, 0x6b, 0x7a, 0x68,
        0x9e, 0xdc, 0xc0, 0x70, 0x92, 0xac, 0x73, 0xd6, 0x79, 0x55, 0x73, 0x5e, 0xd5, 0xf8, 0xff, 0xfb, 0xaa, 0x66, 0xd3, 0x5e, 0x3e, 0xaf,
        0x65, 0xce, 0x6b, 0x99, 0xf3, 0x5a, 0xc6, 0xf5, 0xf6, 0xf5, 0x41, 0x6a, 0x99, 0xbc, 0x7c, 0x81, 0xca, 0x26, 0xef, 0xf2, 0xe8, 0x9e,
        0x4f, 0xbc, 0xb1, 0xe5, 0x33, 0x21, 0x94, 0xee, 0xcb, 0x05, 0xc5, 0xbb, 0x42, 0x77, 0x7d, 0x04, 0xbc, 0xd1, 0x8c, 0x07, 0x30, 0xa8,
        0xdb, 0x51, 0xba, 0x27, 0xb9, 0x6a, 0x01, 0xce, 0x22, 0xf8, 0x9a, 0x35, 0x98, 0x2c, 0xdc, 0x94, 0x23, 0x2d, 0xe3, 0x71, 0x26, 0x3f,
        0x27, 0x32, 0xda, 0x8f, 0xd0, 0x0c, 0x5a, 0x43, 0x65, 0xdd, 0xc0, 0x9c, 0x8a, 0x4c, 0xf5, 0x54, 0x78, 0x33, 0x26, 0xa0, 0x63, 0xa4,
        0x87, 0x75, 0x2b, 0x15, 0x9f, 0xd0, 0xad, 0xfb, 0x4e, 0xf3, 0x78, 0x8f, 0x8d, 0xd3, 0x4e, 0x67, 0xb9, 0xac, 0xba, 0x9a, 0xa9, 0x0b,
        0x05, 0x92, 0xf9, 0x78, 0x29, 0x5c, 0x8d, 0x43, 0x97, 0x4a, 0xa6, 0xe8, 0x5a, 0x3d, 0xef, 0xde, 0xad, 0xd4, 0xeb, 0x7e, 0xe8, 0x54,
        0x77, 0x59, 0x97, 0x06, 0x28, 0xd9, 0xd3, 0x18, 0x61, 0x4c, 0x66, 0x1b, 0x51, 0x75, 0x18, 0x51, 0x5f, 0x0e, 0x42, 0x14, 0x5e, 0x67,
        0x84, 0x5e, 0xd9, 0x99, 0x58, 0xd1, 0x74, 0x58, 0xd1, 0x50, 0xea, 0x97, 0xa1, 0x5a, 0x46, 0x71, 0xe5, 0x0a, 0x30, 0x6d, 0x15, 0x15,
        0x78, 0xe5, 0xf6, 0xe0, 0x45, 0xbd, 0xe5, 0x87, 0x41, 0xda, 0x41, 0x86, 0x66, 0x1c, 0x94, 0xe7, 0x63, 0x15, 0xa7, 0xb4, 0x99, 0xbc,
        0x8c, 0xae, 0x0a, 0xce, 0x99, 0x46, 0x7a, 0x93, 0x33, 0xa9, 0x99, 0x01, 0x50, 0x62, 0x2f, 0x33, 0x20, 0x8f, 0x74, 0x53, 0xd9, 0xba,
        0x71, 0x79, 0x6a, 0x75, 0x69, 0xaa, 0xbd, 0x45, 0xa4, 0x2d, 0x23, 0x8c, 0x74, 0xb3, 0x8d, 0x30, 0xd2, 0x30, 0x82, 0x17, 0xe1, 0x2c,
        0x3b, 0xcd, 0x96, 0xfb, 0x59, 0xc6, 0xba, 0x99, 0x87, 0xd4, 0x32, 0x4f, 0xb9, 0x62, 0xb9, 0x1b, 0x72, 0x33, 0xea, 0x8d, 0x0f, 0x11,
        0x6b, 0x45, 0x22, 0x27, 0xb8, 0x81, 0x26, 0x26, 0x53, 0xd0, 0xc4, 0x3b, 0x6e, 0xf9, 0xb5, 0x6a, 0x08, 0xb7, 0x2a, 0x23, 0x34, 0x6b,
        0xf9, 0x13, 0xe8, 0x18, 0xc3, 0xd7, 0x78, 0x06, 0xb9, 0x23, 0xd4, 0x5b, 0x17, 0xa2, 0x53, 0xb8, 0x76, 0x19, 0x49, 0x9e, 0x6e, 0xf8,
        0x77, 0x61, 0x96, 0x19, 0x17, 0xb2, 0x87, 0x44, 0x94, 0x3a, 0x5c, 0x93, 0x4e, 0xca, 0x06, 0x31, 0x91, 0x98, 0x7b, 0x94, 0xc4, 0x2d,
        0x5f, 0x2d, 0x7f, 0x95, 0x0d, 0x34, 0xd1, 0x1c, 0xa2, 0x6d, 0x2b, 0x57, 0x80, 0x10, 0x3e, 0x5a, 0xe3, 0x9a, 0x40, 0x2b, 0x1f, 0x9b,
        0x71, 0x10, 0x74, 0x3b, 0xc8, 0x78, 0x32, 0xc1, 0x23, 0x69, 0x86, 0xdd, 0x18, 0x51, 0x9e, 0x4e, 0x1f, 0x81, 0xe1, 0x53, 0xae, 0x70,
        0xfe, 0xaa, 0xc5, 0xdf, 0x1d, 0xac, 0x24, 0xd9, 0x1c, 0xc2, 0xbd, 0x1f, 0x8d, 0x8f, 0xbd, 0x03, 0x3a, 0xe7, 0x37, 0x11, 0xa4, 0x58,
        0x58, 0x2f, 0x2b, 0x07, 0x8e, 0x89, 0x80, 0x8b, 0x83, 0x72, 0xea, 0xcd, 0x31, 0x81, 0x9b, 0xb0, 0x15, 0x91, 0xe5, 0xf9, 0x77, 0xe2,
        0x60, 0xca, 0x68, 0xd7, 0xbc, 0x8a, 0xd2, 0x39, 0x94, 0x8e, 0x23, 0x3a, 0x8b, 0x50, 0x76, 0xa2, 0x98, 0x64, 0x9e, 0xc2, 0x35, 0x89,
        0xae, 0xcc, 0xd1, 0x4f, 0x2b, 0x1f, 0x18, 0x4f, 0xd9, 0x9a, 0xc1, 0xa1, 0xeb, 0x2e, 0x3c, 0x98, 0xaa, 0x03, 0xf6, 0xbd, 0x4f, 0xdd,
        0x37, 0x1f, 0xd5, 0xca, 0x73, 0x06, 0x69, 0xe6, 0x67, 0xa6, 0xc5, 0x2a, 0xea, 0xd4, 0x74, 0x93, 0xe9, 0x87, 0x3b, 0xe4, 0x0d, 0xab,
        0xf2, 0x43, 0xd4, 0xb2, 0x2a, 0xa5, 0x6e, 0xfd, 0x4e, 0x2d, 0x72, 0xae, 0x6b, 0x2e, 0xb9, 0x0e, 0x12, 0xd5, 0x79, 0x4a, 0xbc, 0xe1,
        0xd4, 0x7d, 0x8b, 0x03, 0xc1, 0x30, 0x2d, 0x9f, 0xcc, 0x32, 0x4d, 0x59, 0xbc, 0x4e, 0xc3, 0x8a, 0xb3, 0xb3, 0x51, 0xdb, 0xb4, 0x33,
        0x2c, 0x08, 0x0c, 0x4f, 0xd4, 0x36, 0xf8, 0x6d, 0x75, 0x46, 0x38, 0x3d, 0xf1, 0xae, 0x27, 0x3f, 0xc8, 0x9d, 0xcc, 0x5a, 0x75, 0x40,
        0x2c, 0xeb, 0x4a, 0x9d, 0xf8, 0xfa, 0xca, 0xdc, 0xbc, 0xd5, 0x66, 0x07, 0x77, 0x81, 0x3c, 0x7a, 0x70, 0x7f, 0x38, 0xa7, 0x52, 0xe8,
        0x50, 0x42, 0x6f, 0x97, 0x23, 0x28, 0xfa, 0xd2, 0x1b, 0xc8, 0x94, 0x36, 0x60, 0x8b, 0xdc, 0x93, 0x59, 0x8d, 0x08, 0xdf, 0xbc, 0x39,
        0x27, 0x2d, 0xff, 0x7e, 0x29, 0x6c, 0x07, 0xdd, 0x4a, 0xd8, 0x2d, 0x94, 0x1a, 0x61, 0xbf, 0x10, 0x54, 0x83, 0x52, 0xa1, 0x11, 0xb6,
        0xab, 0x85, 0x76, 0x18, 0x56, 0xcb, 0xfd, 0xb0, 0x5c, 0xea, 0x75, 0x2a, 0x0f, 0xe0, 0x60, 0x91, 0x51, 0x5c, 0x0e, 0xd3, 0xeb, 0xfa,
        0x01, 0x5c, 0x61, 0xd0, 0x45, 0x76, 0x69, 0xaf, 0xc7, 0xd7, 0x2e, 0xee, 0xe3, 0xe5, 0x2d, 0xcd, 0x85, 0x11, 0x8b, 0x8b, 0x4c, 0x5f,
        0xcc, 0x17, 0xb5, 0xe1, 0xfa, 0xe2, 0xbe, 0x5c, 0xd9, 0x7c, 0x71, 0xef, 0x11, 0x20, 0x9d, 0xfb, 0xb5, 0xca, 0xa0, 0x59, 0x6d, 0x76,
        0x6a, 0x85, 0x66, 0xb5, 0x3d, 0x28, 0x04, 0xbd, 0x4e, 0xa3, 0xd0, 0xec, 0xd6, 0x3a, 0x85, 0x5e, 0xad, 0x5b, 0xef, 0x0d, 0x7a, 0xdd,
        0xb0, 0xd1, 0x1c, 0x3c, 0xf0, 0xbd, 0x23, 0x0d, 0x0e, 0xda, 0xd5, 0x6e, 0x50, 0xeb, 0x37, 0x0a, 0xb5, 0x72, 0xb7, 0x5b, 0x08, 0x6a,
        0x25, 0x65, 0x7e, 0xa3, 0x59, 0xa8, 0x07, 0x95, 0x4a, 0x3b, 0xa8, 0xb7, 0x1b, 0xfd, 0xa0, 0xfd, 0x20, 0x2b, 0x63, 0x60, 0xe5, 0x29,
        0x7d, 0x64, 0xbe, 0x00, 0xf7, 0x6a, 0xbb, 0xb6, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00,
        0x06, 0x00, 0x08, 0x00, 0x00, 0x00, 0x21, 0x00, 0xff, 0x6b, 0x0c, 0xe9, 0xcd, 0x01, 0x00, 0x00, 0xb5, 0x03, 0x00, 0x00, 0x18, 0x00,
        0x00, 0x00, 0x78, 0x6c, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x68, 0x65, 0x65, 0x74, 0x73, 0x2f, 0x73, 0x68, 0x65, 0x65, 0x74, 0x31,
        0x2e, 0x78, 0x6d, 0x6c, 0x9c, 0x93, 0x4d, 0x8b, 0xdb, 0x30, 0x10, 0x86, 0xef, 0x85, 0xfe, 0x07, 0xa1, 0xbb, 0x2d, 0xdb, 0xf1, 0x3a,
        0x89, 0x89, 0xb3, 0x6c, 0x36, 0x0d, 0xdd, 0x43, 0xa1, 0xf4, 0xf3, 0x2c, 0xcb, 0x63, 0x5b, 0xc4, 0x92, 0x8c, 0xa4, 0x6c, 0x12, 0x4a,
        0xff, 0x7b, 0xc7, 0x0e, 0xf1, 0x16, 0x72, 0x09, 0x0b, 0x16, 0x68, 0xc6, 0x9a, 0x67, 0x66, 0xa4, 0x77, 0x56, 0x8f, 0x27, 0xd5, 0x91,
        0x57, 0xb0, 0x4e, 0x1a, 0x5d, 0xd0, 0x38, 0x8c, 0x28, 0x01, 0x2d, 0x4c, 0x25, 0x75, 0x53, 0xd0, 0x9f, 0x3f, 0x76, 0xc1, 0x82, 0x12,
        0xe7, 0xb9, 0xae, 0x78, 0x67, 0x34, 0x14, 0xf4, 0x0c, 0x8e, 0x3e, 0xae, 0x3f, 0x7e, 0x58, 0x1d, 0x8d, 0xdd, 0xbb, 0x16, 0xc0, 0x13,
        0x24, 0x68, 0x57, 0xd0, 0xd6, 0xfb, 0x3e, 0x67, 0xcc, 0x89, 0x16, 0x14, 0x77, 0xa1, 0xe9, 0x41, 0xe3, 0x9f, 0xda, 0x58, 0xc5, 0x3d,
        0x9a, 0xb6, 0x61, 0xae, 0xb7, 0xc0, 0xab, 0x31, 0x48, 0x75, 0x2c, 0x89, 0xa2, 0x8c, 0x29, 0x2e, 0x35, 0xbd, 0x10, 0x72, 0x7b, 0x0f,
        0xc3, 0xd4, 0xb5, 0x14, 0xb0, 0x35, 0xe2, 0xa0, 0x40, 0xfb, 0x0b, 0xc4, 0x42, 0xc7, 0x3d, 0xd6, 0xef, 0x5a, 0xd9, 0xbb, 0x2b, 0x4d,
        0x89, 0x7b, 0x70, 0x8a, 0xdb, 0xfd, 0xa1, 0x0f, 0x84, 0x51, 0x3d, 0x22, 0x4a, 0xd9, 0x49, 0x7f, 0x1e, 0xa1, 0x94, 0x28, 0x91, 0xbf,
        0x34, 0xda, 0x58, 0x5e, 0x76, 0xd8, 0xf7, 0x29, 0x4e, 0xb9, 0x20, 0x27, 0x8b, 0x5f, 0x82, 0x6b, 0x76, 0x4d, 0x33, 0xfa, 0x6f, 0x32,
        0x29, 0x29, 0xac, 0x71, 0xa6, 0xf6, 0x21, 0x92, 0xd9, 0xa5, 0xe6, 0xdb, 0xf6, 0x97, 0x6c, 0xc9, 0xb8, 0x98, 0x48, 0xb7, 0xfd, 0xdf,
        0x85, 0x89, 0x53, 0x66, 0xe1, 0x55, 0x0e, 0x0f, 0xf8, 0x86, 0x4a, 0xde, 0x57, 0x52, 0xfc, 0x30, 0xb1, 0x92, 0x37, 0xd8, 0xec, 0x9d,
        0xb0, 0x6c, 0x82, 0x0d, 0xd7, 0x65, 0xf3, 0x83, 0xac, 0x0a, 0xfa, 0x27, 0x4a, 0x97, 0xbb, 0x4d, 0xbc, 0x49, 0x83, 0xe4, 0x29, 0x8b,
        0x83, 0x34, 0x4b, 0x67, 0xc1, 0x62, 0x11, 0x67, 0xc1, 0x62, 0x33, 0xcf, 0x3e, 0x3d, 0xcf, 0xb2, 0xdd, 0x36, 0xdd, 0xfc, 0xa5, 0xeb,
        0x55, 0x25, 0xf1, 0x85, 0x87, 0xae, 0x88, 0x85, 0xba, 0xa0, 0x4f, 0x31, 0x65, 0xeb, 0xd5, 0x28, 0x9e, 0x5f, 0x12, 0x8e, 0xee, 0xbf,
        0x3d, 0xf1, 0xbc, 0xfc, 0x0e, 0x1d, 0x08, 0x0f, 0x98, 0x20, 0xa6, 0x64, 0xd0, 0x66, 0x69, 0xcc, 0x7e, 0x38, 0xf8, 0x82, 0xae, 0x68,
        0x08, 0x65, 0x37, 0xb1, 0xbb, 0x51, 0x9b, 0x5f, 0x2d, 0x29, 0xb9, 0x83, 0x67, 0xd3, 0xfd, 0x96, 0x95, 0x6f, 0x11, 0x80, 0x33, 0x50,
        0x41, 0xcd, 0x0f, 0x9d, 0xff, 0x66, 0x8e, 0x9f, 0x41, 0x36, 0xad, 0x47, 0x6f, 0x86, 0x3d, 0x0c, 0x22, 0xc8, 0xab, 0xf3, 0x16, 0x9c,
        0x40, 0xf5, 0x21, 0x38, 0x4c, 0xa6, 0xaa, 0xb6, 0xdc, 0x73, 0x4c, 0xd3, 0xf3, 0x06, 0xbe, 0x70, 0xdb, 0x48, 0xed, 0x48, 0x07, 0xf5,
        0x78, 0x68, 0x4e, 0x89, 0xbd, 0x50, 0xa2, 0x10, 0xf7, 0xde, 0xf4, 0x43, 0xe8, 0xfc, 0x81, 0x92, 0xd2, 0x78, 0x6f, 0xd4, 0xd5, 0x6a,
        0x71, 0x3c, 0x00, 0x65, 0x10, 0x85, 0x78, 0x61, 0xb5, 0x31, 0xfe, 0x6a, 0x0c, 0xe5, 0x4f, 0x03, 0xb7, 0xfe, 0x07, 0x00, 0x00, 0xff,
        0xff, 0x03, 0x00, 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x06, 0x00, 0x08, 0x00, 0x00, 0x00, 0x21, 0x00, 0xc2, 0x5e, 0x59, 0x08, 0x90,
        0x01, 0x00, 0x00, 0x1b, 0x03, 0x00, 0x00, 0x10, 0x00, 0x08, 0x01, 0x64, 0x6f, 0x63, 0x50, 0x72, 0x6f, 0x70, 0x73, 0x2f, 0x61, 0x70,
        0x70, 0x2e, 0x78, 0x6d, 0x6c, 0x20, 0xa2, 0x04, 0x01, 0x28, 0xa0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x92, 0x4d, 0x6f, 0xdb, 0x30, 0x0c, 0x86, 0xef, 0x03, 0xfa, 0x1f, 0x0c, 0xdd, 0x1b, 0x39, 0x6d,
        0x51, 0x0c, 0x81, 0xac, 0x62, 0x48, 0x57, 0xf4, 0xb0, 0x62, 0x01, 0x92, 0x76, 0x67, 0x4e, 0xa6, 0x63, 0xa1, 0xb2, 0x24, 0x88, 0xac,
        0x91, 0xec, 0xd7, 0x4f, 0xb6, 0xd1, 0xd4, 0xd9, 0x76, 0xda, 0x8d, 0x1f, 0x2f, 0x5e, 0x3e, 0xa2, 0xa8, 0xee, 0x0e, 0x9d, 0x2b, 0x7a,
        0x4c, 0x64, 0x83, 0xaf, 0xc4, 0x72, 0x51, 0x8a, 0x02, 0xbd, 0x09, 0xb5, 0xf5, 0xfb, 0x4a, 0x3c, 0xef, 0x1e, 0x2e, 0x3f, 0x8b, 0x82,
        0x18, 0x7c, 0x0d, 0x2e, 0x78, 0xac, 0xc4, 0x11, 0x49, 0xdc, 0xe9, 0x8b, 0x4f, 0x6a, 0x93, 0x42, 0xc4, 0xc4, 0x16, 0xa9, 0xc8, 0x16,
        0x9e, 0x2a, 0xd1, 0x32, 0xc7, 0x95, 0x94, 0x64, 0x5a, 0xec, 0x80, 0x16, 0xb9, 0xed, 0x73, 0xa7, 0x09, 0xa9, 0x03, 0xce, 0x69, 0xda,
        0xcb, 0xd0, 0x34, 0xd6, 0xe0, 0x7d, 0x30, 0x6f, 0x1d, 0x7a, 0x96, 0x57, 0x65, 0x79, 0x2b, 0xf1, 0xc0, 0xe8, 0x6b, 0xac, 0x2f, 0xe3,
        0xc9, 0x50, 0x4c, 0x8e, 0xab, 0x9e, 0xff, 0xd7, 0xb4, 0x0e, 0x66, 0xe0, 0xa3, 0x97, 0xdd, 0x31, 0x66, 0x60, 0xad, 0xbe, 0xc4, 0xe8,
        0xac, 0x01, 0xce, 0xaf, 0xd4, 0x4f, 0xd6, 0xa4, 0x40, 0xa1, 0xe1, 0xe2, 0x09, 0x8c, 0xf5, 0x1c, 0xa8, 0x2d, 0xbe, 0x1e, 0x0c, 0x3a,
        0x25, 0xe7, 0x32, 0x95, 0x39, 0xb7, 0x68, 0xde, 0x92, 0xe5, 0xa3, 0x2e, 0x95, 0x9c, 0xa7, 0x6a, 0x6b, 0xc0, 0xe1, 0x3a, 0x8f, 0xd0,
        0x0d, 0x38, 0x42, 0x25, 0x3f, 0x0a, 0xea, 0x11, 0x61, 0x58, 0xdf, 0x06, 0x6c, 0x22, 0xad, 0x7a, 0x5e, 0xf5, 0x68, 0x38, 0xa4, 0x82,
        0xec, 0xaf, 0xbc, 0xc0, 0x2b, 0x51, 0xfc, 0x04, 0xc2, 0x01, 0xac, 0x12, 0x3d, 0x24, 0x0b, 0x9e, 0x33, 0xe0, 0x20, 0x9b, 0x92, 0x31,
        0x76, 0x91, 0x38, 0xe9, 0x1f, 0x21, 0xbd, 0x52, 0x8b, 0xc8, 0xa4, 0x64, 0x16, 0x4c, 0xc5, 0x31, 0x9c, 0x6b, 0xe7, 0xb1, 0xbd, 0xd1,
        0xcb, 0x51, 0x90, 0x83, 0x73, 0xe1, 0x60, 0x30, 0x81, 0xe4, 0xc6, 0x39, 0xe2, 0xce, 0xb2, 0x43, 0xfa, 0xde, 0x6c, 0x20, 0xf1, 0x3f,
        0x88, 0x97, 0x73, 0xe2, 0x91, 0x61, 0xe2, 0x9d, 0x70, 0xb6, 0x03, 0xdf, 0x34, 0x73, 0xce, 0x37, 0x3e, 0x39, 0x4f, 0xfa, 0xc3, 0x7b,
        0x1d, 0xba, 0x08, 0xfe, 0x98, 0x1b, 0xa7, 0xe8, 0x9b, 0xf5, 0xaf, 0xf4, 0x1c, 0x77, 0xe1, 0x1e, 0x18, 0xdf, 0xd7, 0x79, 0x5e, 0x54,
        0xdb, 0x16, 0x12, 0xd6, 0xf9, 0x07, 0x4e, 0xeb, 0x3e, 0x15, 0xd4, 0x63, 0xde, 0x64, 0x72, 0x83, 0xc9, 0xba, 0x05, 0xbf, 0xc7, 0xfa,
        0x5d, 0xf3, 0x77, 0x63, 0x38, 0x83, 0x97, 0xe9, 0xd6, 0xf5, 0xf2, 0x76, 0x51, 0x5e, 0x97, 0xf9, 0x5f, 0x67, 0x35, 0x25, 0x3f, 0xae,
        0x5a, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x06, 0x00, 0x08, 0x00, 0x00, 0x00, 0x21,
        0x00, 0xbd, 0xde, 0xac, 0xb8, 0x45, 0x01, 0x00, 0x00, 0x6f, 0x02, 0x00, 0x00, 0x11, 0x00, 0x08, 0x01, 0x64, 0x6f, 0x63, 0x50, 0x72,
        0x6f, 0x70, 0x73, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x78, 0x6d, 0x6c, 0x20, 0xa2, 0x04, 0x01, 0x28, 0xa0, 0x00, 0x01, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94, 0x92, 0x5f, 0x4b, 0xc3, 0x30, 0x14, 0xc5, 0xdf, 0x05,
        0xbf, 0x43, 0xc9, 0x7b, 0x9b, 0x66, 0x1b, 0x63, 0x96, 0xb6, 0x83, 0x29, 0x7b, 0xd1, 0x81, 0xe0, 0x44, 0xf1, 0x2d, 0x24, 0x77, 0x5b,
        0xb0, 0xf9, 0x43, 0x12, 0xd7, 0xed, 0xdb, 0x9b, 0xb6, 0x5b, 0xad, 0xd4, 0x17, 0x1f, 0x93, 0x73, 0xee, 0x2f, 0xe7, 0x5c, 0x92, 0x2f,
        0x4f, 0xb2, 0x8a, 0x8e, 0x60, 0x9d, 0xd0, 0xaa, 0x40, 0x24, 0x49, 0x51, 0x04, 0x8a, 0x69, 0x2e, 0xd4, 0xbe, 0x40, 0xaf, 0xdb, 0x75,
        0xbc, 0x40, 0x91, 0xf3, 0x54, 0x71, 0x5a, 0x69, 0x05, 0x05, 0x3a, 0x83, 0x43, 0xcb, 0xf2, 0xf6, 0x26, 0x67, 0x26, 0x63, 0xda, 0xc2,
        0xb3, 0xd5, 0x06, 0xac, 0x17, 0xe0, 0xa2, 0x40, 0x52, 0x2e, 0x63, 0xa6, 0x40, 0x07, 0xef, 0x4d, 0x86, 0xb1, 0x63, 0x07, 0x90, 0xd4,
        0x25, 0xc1, 0xa1, 0x82, 0xb8, 0xd3, 0x56, 0x52, 0x1f, 0x8e, 0x76, 0x8f, 0x0d, 0x65, 0x9f, 0x74, 0x0f, 0x78, 0x92, 0xa6, 0x73, 0x2c,
        0xc1, 0x53, 0x4e, 0x3d, 0xc5, 0x0d, 0x30, 0x36, 0x3d, 0x11, 0x5d, 0x90, 0x9c, 0xf5, 0x48, 0xf3, 0x65, 0xab, 0x16, 0xc0, 0x19, 0x86,
        0x0a, 0x24, 0x28, 0xef, 0x30, 0x49, 0x08, 0xfe, 0xf1, 0x7a, 0xb0, 0xd2, 0xfd, 0x39, 0xd0, 0x2a, 0x03, 0xa7, 0x14, 0xfe, 0x6c, 0x42,
        0xa7, 0x4b, 0xdc, 0x21, 0x9b, 0xb3, 0x4e, 0xec, 0xdd, 0x27, 0x27, 0x7a, 0x63, 0x5d, 0xd7, 0x49, 0x3d, 0x6d, 0x63, 0x84, 0xfc, 0x04,
        0xbf, 0x6f, 0x9e, 0x5e, 0xda, 0xaa, 0xb1, 0x50, 0xcd, 0xae, 0x18, 0xa0, 0x32, 0xe7, 0x2c, 0x63, 0x16, 0xa8, 0xd7, 0xb6, 0x7c, 0x04,
        0xa5, 0xc0, 0x1f, 0xa2, 0x15, 0xad, 0x5c, 0x05, 0xc7, 0x1c, 0x0f, 0xb4, 0x66, 0x8f, 0x15, 0x75, 0x7e, 0x13, 0x56, 0xbe, 0x13, 0xc0,
        0x57, 0xe7, 0xb1, 0x7d, 0x6c, 0x09, 0xf4, 0xb6, 0x4c, 0xf7, 0x04, 0xf0, 0x28, 0xc4, 0xcb, 0xba, 0x32, 0x57, 0xe5, 0x6d, 0x7a, 0xff,
        0xb0, 0x5d, 0xa3, 0x72, 0x92, 0x92, 0xbb, 0x38, 0x5d, 0xc4, 0x64, 0xbe, 0x4d, 0xd3, 0x6c, 0x3a, 0xcb, 0xc8, 0xec, 0xa3, 0x49, 0xf0,
        0x6b, 0xbe, 0x89, 0xdb, 0x5d, 0xc8, 0x4b, 0x8e, 0xff, 0x10, 0x27, 0xf3, 0x01, 0xf1, 0x0a, 0x28, 0x73, 0x3c, 0xfa, 0x22, 0xe5, 0x37,
        0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x02, 0x00, 0x08, 0x00, 0x9a, 0xab, 0x0f, 0x4f, 0x5e,
        0xff, 0xec, 0xaa, 0x93, 0x00, 0x00, 0x00, 0xb2, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x78, 0x6c, 0x2f, 0x73, 0x68, 0x61, 0x72,
        0x65, 0x64, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x78, 0x6d, 0x6c, 0x35, 0x8d, 0x41, 0x0a, 0xc2, 0x30, 0x10, 0x45, 0xf7,
        0x82, 0x77, 0x08, 0xb3, 0xd7, 0xa9, 0x2e, 0x44, 0x24, 0x49, 0x17, 0x82, 0x27, 0xd0, 0x03, 0x84, 0x76, 0x6c, 0x03, 0xcd, 0xa4, 0x66,
        0xa6, 0xa2, 0xb7, 0x37, 0x5d, 0xb8, 0xf8, 0xf0, 0x1f, 0x9f, 0xcf, 0xb3, 0xed, 0x27, 0x4d, 0xe6, 0x4d, 0x45, 0x62, 0x66, 0x07, 0x87,
        0x7d, 0x03, 0x86, 0xb8, 0xcb, 0x7d, 0xe4, 0xc1, 0xc1, 0xe3, 0x7e, 0xdb, 0x9d, 0xc1, 0x88, 0x06, 0xee, 0xc3, 0x94, 0x99, 0x1c, 0x7c,
        0x49, 0xa0, 0xf5, 0xdb, 0x8d, 0x15, 0x51, 0x53, 0xbf, 0x2c, 0x0e, 0x46, 0xd5, 0xf9, 0x82, 0x28, 0xdd, 0x48, 0x29, 0xc8, 0x3e, 0xcf,
        0xc4, 0x75, 0x79, 0xe6, 0x92, 0x82, 0x56, 0x2c, 0x03, 0xca, 0x5c, 0x28, 0xf4, 0x32, 0x12, 0x69, 0x9a, 0xf0, 0xd8, 0x34, 0x27, 0x4c,
        0x21, 0x32, 0x98, 0x2e, 0x2f, 0xac, 0xd5, 0x0b, 0x66, 0xe1, 0xf8, 0x5a, 0xe8, 0xfa, 0x67, 0x6f, 0x25, 0x7a, 0xab, 0xde, 0xe2, 0x9a,
        0xb5, 0x63, 0x35, 0x56, 0xf1, 0x0f, 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x02, 0x00, 0x08, 0x00, 0x99, 0x64, 0xef, 0x50, 0xd9, 0x19,
        0xd7, 0x73, 0x3f, 0x01, 0x00, 0x00, 0x7e, 0x04, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x5b, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
        0x5f, 0x54, 0x79, 0x70, 0x65, 0x73, 0x5d, 0x2e, 0x78, 0x6d, 0x6c, 0xad, 0x93, 0xcd, 0x4e, 0xc3, 0x30, 0x10, 0x84, 0xef, 0x3c, 0x45,
        0xe4, 0x2b, 0x4a, 0xdc, 0x72, 0x40, 0x08, 0x35, 0xed, 0x81, 0x9f, 0x23, 0x54, 0xa2, 0x3c, 0x80, 0xb1, 0x37, 0x8d, 0xd5, 0xf8, 0x47,
        0xbb, 0x6e, 0x69, 0xdf, 0x9e, 0x4d, 0x52, 0x21, 0x40, 0x55, 0x03, 0xb4, 0x97, 0x58, 0xf1, 0xce, 0xcc, 0x37, 0x3e, 0xec, 0x64, 0xb6,
        0x75, 0x4d, 0xb6, 0x01, 0x24, 0x1b, 0x7c, 0x29, 0xc6, 0xc5, 0x48, 0x64, 0xe0, 0x75, 0x30, 0xd6, 0x2f, 0x4b, 0xf1, 0xba, 0x78, 0xcc,
        0x6f, 0xc4, 0x6c, 0x3a, 0x59, 0xec, 0x22, 0x50, 0xc6, 0x52, 0x4f, 0xa5, 0xa8, 0x53, 0x8a, 0xb7, 0x52, 0x92, 0xae, 0xc1, 0x29, 0x2a,
        0x42, 0x04, 0xcf, 0x93, 0x2a, 0xa0, 0x53, 0x89, 0x7f, 0x71, 0x29, 0xa3, 0xd2, 0x2b, 0xb5, 0x04, 0x79, 0x35, 0x1a, 0x5d, 0x4b, 0x1d,
        0x7c, 0x02, 0x9f, 0xf2, 0xd4, 0x66, 0x88, 0xe9, 0xe4, 0x1e, 0x2a, 0xb5, 0x6e, 0x52, 0xf6, 0xb0, 0xe5, 0xeb, 0x1e, 0x8b, 0xd0, 0x90,
        0xc8, 0xee, 0x7a, 0x61, 0xcb, 0x2a, 0x85, 0x8a, 0xb1, 0xb1, 0x5a, 0x25, 0x9e, 0xcb, 0x8d, 0x37, 0x3f, 0x28, 0xf9, 0x9e, 0x50, 0xb0,
        0xb3, 0xd3, 0x50, 0x6d, 0x23, 0x5d, 0xb2, 0x40, 0xc8, 0x83, 0x04, 0x9e, 0x1c, 0x01, 0xec, 0x7d, 0xcf, 0x1b, 0x40, 0xb4, 0x06, 0xb2,
        0xb9, 0xc2, 0xf4, 0xa4, 0x1c, 0xab, 0xe4, 0xb6, 0x91, 0xef, 0x01, 0x57, 0x6f, 0x21, 0xac, 0x0a, 0x96, 0xfd, 0xad, 0x65, 0xa8, 0x2a,
        0xab, 0xc1, 0x04, 0xbd, 0x76, 0x6c, 0x29, 0x28, 0x22, 0x28, 0x43, 0x35, 0x40, 0x72, 0x4d, 0xd1, 0x9d, 0x85, 0x53, 0xd6, 0x5f, 0x0e,
        0xf3, 0x3b, 0x31, 0xc9, 0xee, 0x18, 0x9f, 0xb9, 0xc8, 0x67, 0xfe, 0x40, 0x8f, 0x54, 0x83, 0x83, 0xfe, 0x7b, 0x7a, 0x85, 0x2e, 0x66,
        0x00, 0x48, 0x69, 0xd7, 0x00, 0x9d, 0x8c, 0xfa, 0xfe, 0xda, 0x3e, 0x74, 0x88, 0x5c, 0x2b, 0x04, 0xf3, 0x92, 0x90, 0xd7, 0xe0, 0xec,
        0x05, 0xbe, 0x64, 0x1f, 0xed, 0xc1, 0xfe, 0x39, 0x86, 0x48, 0x52, 0x07, 0x84, 0xb6, 0xc4, 0xff, 0x56, 0xa4, 0x75, 0xe7, 0x11, 0x79,
        0x8a, 0xc9, 0xc2, 0xef, 0x88, 0x1c, 0x7d, 0xf2, 0xab, 0xa1, 0xdd, 0x3e, 0x03, 0xe6, 0x00, 0x5b, 0xb6, 0x79, 0x34, 0xbd, 0xf8, 0x00,
        0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x02, 0x00, 0x08, 0x00, 0xa7, 0x64, 0xef, 0x50, 0x59, 0xaf, 0xf9, 0x51, 0xdc, 0x00, 0x00, 0x00,
        0xa8, 0x02, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x78, 0x6c, 0x2f, 0x5f, 0x72, 0x65, 0x6c, 0x73, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x62,
        0x6f, 0x6f, 0x6b, 0x2e, 0x78, 0x6d, 0x6c, 0x2e, 0x72, 0x65, 0x6c, 0x73, 0xad, 0x92, 0xcd, 0x6a, 0xc3, 0x30, 0x10, 0x84, 0xef, 0x7d,
        0x0a, 0xb1, 0xf7, 0x5a, 0x76, 0x5a, 0x4a, 0x29, 0x51, 0x72, 0x29, 0x85, 0x5c, 0xdb, 0xf4, 0x01, 0x84, 0xbc, 0xb6, 0x4c, 0x6c, 0x49,
        0xec, 0x6e, 0x7f, 0xf2, 0xf6, 0x11, 0x0e, 0x24, 0x31, 0x84, 0x90, 0x83, 0x4f, 0x62, 0x46, 0xda, 0x99, 0x4f, 0xb0, 0xcb, 0xf5, 0xff,
        0xd0, 0xab, 0x5f, 0x24, 0xee, 0x62, 0x30, 0x50, 0x15, 0x25, 0x28, 0x0c, 0x2e, 0xd6, 0x5d, 0x68, 0x0d, 0x7c, 0x6f, 0x3f, 0x1e, 0x5f,
        0x61, 0xbd, 0x5a, 0x7e, 0x62, 0x6f, 0x25, 0xbf, 0x60, 0xdf, 0x25, 0x56, 0x79, 0x24, 0xb0, 0x01, 0x2f, 0x92, 0xde, 0xb4, 0x66, 0xe7,
        0x71, 0xb0, 0x5c, 0xc4, 0x84, 0x21, 0xdf, 0x34, 0x91, 0x06, 0x2b, 0x59, 0x52, 0xab, 0x93, 0x75, 0x3b, 0xdb, 0xa2, 0x5e, 0x94, 0xe5,
        0x8b, 0xa6, 0xcb, 0x0c, 0x98, 0x66, 0xaa, 0x4d, 0x6d, 0x80, 0x36, 0xf5, 0x33, 0xa8, 0xed, 0x3e, 0xe1, 0x3d, 0xd9, 0xb1, 0x69, 0x3a,
        0x87, 0xef, 0xd1, 0xfd, 0x0c, 0x18, 0xe4, 0x4a, 0x85, 0x66, 0x6f, 0x09, 0xeb, 0x2f, 0xa1, 0xfc, 0x17, 0xce, 0xc1, 0x96, 0x5a, 0x14,
        0x03, 0x13, 0xbb, 0xc8, 0xa9, 0xa0, 0xaf, 0xc3, 0x3c, 0xcd, 0x0a, 0x23, 0xfb, 0x1e, 0x2f, 0x28, 0x46, 0x7d, 0xb3, 0x7e, 0x31, 0x67,
        0xbd, 0xe4, 0x59, 0x3c, 0xb7, 0x8f, 0xf2, 0x68, 0x56, 0xb7, 0x18, 0xaa, 0x39, 0x19, 0xfe, 0x22, 0xed, 0xd8, 0x23, 0xca, 0x99, 0xe3,
        0x64, 0xb1, 0x1e, 0x8f, 0x13, 0x8c, 0x9e, 0x6c, 0xdc, 0xea, 0xe1, 0x00, 0x50, 0x4b, 0x01, 0x02, 0x2d, 0x00, 0x14, 0x00, 0x06, 0x00,
        0x08, 0x00, 0x00, 0x00, 0x21, 0x00, 0xb5, 0x55, 0x30, 0x23, 0xf4, 0x00, 0x00, 0x00, 0x4c, 0x02, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x72, 0x65, 0x6c, 0x73, 0x2f, 0x2e, 0x72,
        0x65, 0x6c, 0x73, 0x50, 0x4b, 0x01, 0x02, 0x2d, 0x00, 0x14, 0x00, 0x06, 0x00, 0x08, 0x00, 0x00, 0x00, 0x21, 0x00, 0x47, 0x88, 0xbc,
        0xe2, 0x5d, 0x03, 0x00, 0x00, 0x35, 0x08, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x25, 0x03, 0x00, 0x00, 0x78, 0x6c, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x62, 0x6f, 0x6f, 0x6b, 0x2e, 0x78, 0x6d, 0x6c, 0x50, 0x4b,
        0x01, 0x02, 0x2d, 0x00, 0x14, 0x00, 0x06, 0x00, 0x08, 0x00, 0x00, 0x00, 0x21, 0x00, 0xf0, 0x08, 0x58, 0xf4, 0xa5, 0x02, 0x00, 0x00,
        0x52, 0x06, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaf, 0x06, 0x00, 0x00,
        0x78, 0x6c, 0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x73, 0x2e, 0x78, 0x6d, 0x6c, 0x50, 0x4b, 0x01, 0x02, 0x2d, 0x00, 0x14, 0x00, 0x06,
        0x00, 0x08, 0x00, 0x00, 0x00, 0x21, 0x00, 0xc1, 0x17, 0x10, 0xbe, 0x4e, 0x07, 0x00, 0x00, 0xc6, 0x20, 0x00, 0x00, 0x13, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x09, 0x00, 0x00, 0x78, 0x6c, 0x2f, 0x74, 0x68, 0x65, 0x6d,
        0x65, 0x2f, 0x74, 0x68, 0x65, 0x6d, 0x65, 0x31, 0x2e, 0x78, 0x6d, 0x6c, 0x50, 0x4b, 0x01, 0x02, 0x2d, 0x00, 0x14, 0x00, 0x06, 0x00,
        0x08, 0x00, 0x00, 0x00, 0x21, 0x00, 0xff, 0x6b, 0x0c, 0xe9, 0xcd, 0x01, 0x00, 0x00, 0xb5, 0x03, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x10, 0x00, 0x00, 0x78, 0x6c, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x73,
        0x68, 0x65, 0x65, 0x74, 0x73, 0x2f, 0x73, 0x68, 0x65, 0x65, 0x74, 0x31, 0x2e, 0x78, 0x6d, 0x6c, 0x50, 0x4b, 0x01, 0x02, 0x2d, 0x00,
        0x14, 0x00, 0x06, 0x00, 0x08, 0x00, 0x00, 0x00, 0x21, 0x00, 0xc2, 0x5e, 0x59, 0x08, 0x90, 0x01, 0x00, 0x00, 0x1b, 0x03, 0x00, 0x00,
        0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x13, 0x00, 0x00, 0x64, 0x6f, 0x63, 0x50,
        0x72, 0x6f, 0x70, 0x73, 0x2f, 0x61, 0x70, 0x70, 0x2e, 0x78, 0x6d, 0x6c, 0x50, 0x4b, 0x01, 0x02, 0x2d, 0x00, 0x14, 0x00, 0x06, 0x00,
        0x08, 0x00, 0x00, 0x00, 0x21, 0x00, 0xbd, 0xde, 0xac, 0xb8, 0x45, 0x01, 0x00, 0x00, 0x6f, 0x02, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc7, 0x15, 0x00, 0x00, 0x64, 0x6f, 0x63, 0x50, 0x72, 0x6f, 0x70, 0x73,
        0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x78, 0x6d, 0x6c, 0x50, 0x4b, 0x01, 0x02, 0x14, 0x03, 0x14, 0x00, 0x02, 0x00, 0x08, 0x00, 0x9a,
        0xab, 0x0f, 0x4f, 0x5e, 0xff, 0xec, 0xaa, 0x93, 0x00, 0x00, 0x00, 0xb2, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x01, 0x00, 0x00, 0x00, 0xb6, 0x81, 0x43, 0x18, 0x00, 0x00, 0x78, 0x6c, 0x2f, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x53, 0x74,
        0x72, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x78, 0x6d, 0x6c, 0x50, 0x4b, 0x01, 0x02, 0x14, 0x03, 0x14, 0x00, 0x02, 0x00, 0x08, 0x00, 0x99,
        0x64, 0xef, 0x50, 0xd9, 0x19, 0xd7, 0x73, 0x3f, 0x01, 0x00, 0x00, 0x7e, 0x04, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x01, 0x00, 0x00, 0x00, 0xb6, 0x81, 0x08, 0x19, 0x00, 0x00, 0x5b, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x54, 0x79,
        0x70, 0x65, 0x73, 0x5d, 0x2e, 0x78, 0x6d, 0x6c, 0x50, 0x4b, 0x01, 0x02, 0x14, 0x03, 0x14, 0x00, 0x02, 0x00, 0x08, 0x00, 0xa7, 0x64,
        0xef, 0x50, 0x59, 0xaf, 0xf9, 0x51, 0xdc, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x01, 0x00, 0x00, 0x00, 0xb6, 0x81, 0x78, 0x1a, 0x00, 0x00, 0x78, 0x6c, 0x2f, 0x5f, 0x72, 0x65, 0x6c, 0x73, 0x2f, 0x77, 0x6f, 0x72,
        0x6b, 0x62, 0x6f, 0x6f, 0x6b, 0x2e, 0x78, 0x6d, 0x6c, 0x2e, 0x72, 0x65, 0x6c, 0x73, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00,
        0x0a, 0x00, 0x0a, 0x00, 0x80, 0x02, 0x00, 0x00, 0x8c, 0x1b, 0x00, 0x00, 0x00, 0x00
    };

}    // namespace

XLDocument::XLDocument(const IZipArchive& zipArchive) : m_archive(zipArchive) {}

/**
 * @details An alternative constructor, taking a std::string with the path to the .xlsx package as an argument.
 */
XLDocument::XLDocument(const std::string& docPath, const IZipArchive& zipArchive) : m_archive(zipArchive) { open(docPath); }

/**
 * @details The destructor calls the closeDocument method before the object is destroyed.
 */
XLDocument::~XLDocument() { close(); }

/**
 * @details The openDocument method opens the .xlsx package in the following manner:
 * - Check if a document is already open. If yes, close it.
 * - Create a temporary folder for the contents of the .xlsx package
 * - Unzip the contents of the package to the temporary folder.
 * - load the contents into the data structure for manipulation.
 */
void XLDocument::open(const std::string& fileName)
{
    // Check if a document is already open. If yes, close it.
    // TODO: Consider throwing if a file is already open.
    if (m_archive.isOpen()) close();
    m_filePath = fileName;
    m_archive.open(m_filePath);

    // ===== Add and open the Relationships and [Content_Types] files for the document level.
    m_data.emplace_back(this, "[Content_Types].xml");
    m_data.emplace_back(this, "_rels/.rels");
    m_data.emplace_back(this, "xl/_rels/workbook.xml.rels");

    m_contentTypes     = XLContentTypes(getXmlData("[Content_Types].xml"));
    m_docRelationships = XLRelationships(getXmlData("_rels/.rels"));
    m_wbkRelationships = XLRelationships(getXmlData("xl/_rels/workbook.xml.rels"));

    if (!m_archive.hasEntry("xl/sharedStrings.xml")) execCommand(XLCommand(XLCommandType::AddSharedStrings));

    // ===== Add remaining spreadsheet elements to the vector of XLXmlData objects.
    for (auto& item : m_contentTypes.getContentItems()) {
        if (item.path().substr(0, 4) == "/xl/" && item.path() != "/xl/workbook.xml")
            m_data.emplace_back(/* parentDoc */ this,
                                /* xmlPath   */ item.path().substr(1),
                                /* xmlID     */ m_wbkRelationships.relationshipByTarget(item.path().substr(4)).id(),
                                /* xmlType   */ item.type());

        else
            m_data.emplace_back(/* parentDoc */ this,
                                /* xmlPath   */ item.path().substr(1),
                                /* xmlID     */ m_docRelationships.relationshipByTarget(item.path().substr(1)).id(),
                                /* xmlType   */ item.type());
    }

    // ===== Read shared strings table.
    XMLDocument* sharedStrings = getXmlData("xl/sharedStrings.xml")->getXmlDocument();
    if (!sharedStrings->document_element().attribute("uniqueCount").empty())
        sharedStrings->document_element().remove_attribute(
            "uniqueCount");    // pull request #192 -> remove count & uniqueCount as they are optional
    if (!sharedStrings->document_element().attribute("count").empty())
        sharedStrings->document_element().remove_attribute(
            "count");    // pull request #192 -> remove count & uniqueCount as they are optional

    XMLNode node =
        sharedStrings->document_element().first_child_of_type(pugi::node_element);    // pull request #186: Skip non-element nodes in sst.
    while (node) {
        // ===== Validate si node name.
        using namespace std::literals::string_literals;
        if (node.name() != "si"s) throw XLInputError("xl/sharedStrings.xml sst node name \""s + node.name() + "\" is not \"si\""s);

        // ===== Find first node_element child of si node.
        if (XMLNode elem = node.first_child_of_type(pugi::node_element)) {
            // ===== If shared string is a rich text string
            if (std::string(elem.name()) == "rPh" || std::string(elem.name()) == "phoneticPr") {}
            else if (std::string(elem.name()) == "r") {
                std::string result;
                while (elem) {
                    result += elem.child("t").text().get();
                    elem = elem.next_sibling_of_type(pugi::node_element);
                }
                m_sharedStringCache.emplace_back(result);
            }
            // ===== If shared string is a regular string
            else if (std::string(elem.name()) == "t") {    // 2024-05-03: support a string composed of multiple <t> nodes, because LibreOffice accepts it
                std::string result;
                while (elem) {
                    // if (elem.name() != "t"s)
                    //     throw XLInputError("xl/sharedStrings.xml si node \""s + node.name() + "\" is neiter \"r\" not \"t\""s);
                    result += elem.text().get();
                    elem = elem.next_sibling_of_type(pugi::node_element);
                }
                m_sharedStringCache.emplace_back(result);
            }
            else
                throw XLInputError("xl/sharedStrings.xml si node \""s + node.name() + "\" is neiter \"r\" not \"t\""s);

        }
        node = node.next_sibling_of_type(pugi::node_element);
    }

    // ===== Open the workbook and document property items
    // TODO: If property data doesn't exist, consider creating them, instead of ignoring it.
    m_coreProperties = (hasXmlData("docProps/core.xml") ? XLProperties(getXmlData("docProps/core.xml")) : XLProperties());
    m_appProperties  = (hasXmlData("docProps/app.xml") ? XLAppProperties(getXmlData("docProps/app.xml")) : XLAppProperties());
    m_sharedStrings  = XLSharedStrings(getXmlData("xl/sharedStrings.xml"), &m_sharedStringCache);
    m_workbook       = XLWorkbook(getXmlData("xl/workbook.xml"));
}

/**
 * @details Create a new document. This is done by saving the data in XLTemplate.h in binary format.
 */
void XLDocument::create(const std::string& fileName)
{
    // ===== Create a temporary output file stream.
#ifdef ENABLE_NOWIDE
    nowide::ofstream outfile(fileName, std::ios::binary);
#else
    std::ofstream outfile(fileName, std::ios::binary);
#endif

    // ===== Stream the binary data for an empty workbook to the output file.
    // ===== Casting, in particular reinterpret_cast, is discouraged, but in this case it is unfortunately unavoidable.
    outfile.write(reinterpret_cast<const char*>(templateData), templateSize);    // NOLINT
    outfile.close();

    open(fileName);
}

/**
 * @details The document is closed by deleting the temporary folder structure.
 */
void XLDocument::close()
{
    if (m_archive) m_archive.close();
    m_filePath.clear();
    m_data.clear();

    m_wbkRelationships = XLRelationships();
    m_docRelationships = XLRelationships();
    m_contentTypes     = XLContentTypes();
    m_appProperties    = XLAppProperties();
    m_coreProperties   = XLProperties();
    m_workbook         = XLWorkbook();
}

/**
 * @details Save the document with the same name. The existing file will be overwritten.
 */
void XLDocument::save() { saveAs(m_filePath); }

/**
 * @details Save the document with a new name. If present, the 'calcChain.xml file will be ignored. The reason for this
 * is that changes to the document may invalidate the calcChain.xml file. Deleting will force Excel to re-create the
 * file. This will happen automatically, without the user noticing.
 */
void XLDocument::saveAs(const std::string& fileName)
{
    m_filePath = fileName;

    // ===== Delete the calcChain.xml file in order to force re-calculation of the sheet
    // TODO: Is this the best way to do it? Maybe there is a flag that can be set, that forces re-calculalion.
    execCommand(XLCommand(XLCommandType::ResetCalcChain));

    // ===== Add all xml items to archive and save the archive.
    for (auto& item : m_data) m_archive.addEntry(item.getXmlPath(), item.getRawData());
    m_archive.save(m_filePath);
}

/**
 * @details
 * @todo Currently, this method returns the full path, which is not the intention.
 */
const std::string& XLDocument::name() const { return m_filePath; }

/**
 * @details
 */
const std::string& XLDocument::path() const { return m_filePath; }

/**
 * @details Get a const pointer to the underlying XLWorkbook object.
 */
XLWorkbook XLDocument::workbook() const { return m_workbook; }

/**
 * @details Get the value for a property.
 */
std::string XLDocument::property(XLProperty prop) const
{
    switch (prop) {
        case XLProperty::Application:
            return m_appProperties.property("Application");
        case XLProperty::AppVersion:
            return m_appProperties.property("AppVersion");
        case XLProperty::Category:
            return m_coreProperties.property("cp:category");
        case XLProperty::Company:
            return m_appProperties.property("Company");
        case XLProperty::CreationDate:
            return m_coreProperties.property("dcterms:created");
        case XLProperty::Creator:
            return m_coreProperties.property("dc:creator");
        case XLProperty::Description:
            return m_coreProperties.property("dc:description");
        case XLProperty::DocSecurity:
            return m_appProperties.property("DocSecurity");
        case XLProperty::HyperlinkBase:
            return m_appProperties.property("HyperlinkBase");
        case XLProperty::HyperlinksChanged:
            return m_appProperties.property("HyperlinksChanged");
        case XLProperty::Keywords:
            return m_coreProperties.property("cp:keywords");
        case XLProperty::LastModifiedBy:
            return m_coreProperties.property("cp:lastModifiedBy");
        case XLProperty::LastPrinted:
            return m_coreProperties.property("cp:lastPrinted");
        case XLProperty::LinksUpToDate:
            return m_appProperties.property("LinksUpToDate");
        case XLProperty::Manager:
            return m_appProperties.property("Manager");
        case XLProperty::ModificationDate:
            return m_coreProperties.property("dcterms:modified");
        case XLProperty::ScaleCrop:
            return m_appProperties.property("ScaleCrop");
        case XLProperty::SharedDoc:
            return m_appProperties.property("SharedDoc");
        case XLProperty::Subject:
            return m_coreProperties.property("dc:subject");
        case XLProperty::Title:
            return m_coreProperties.property("dc:title");
        default:
            return "";    // To silence compiler warning.
    }
}

/**
 * @brief extract an integer major version v1 and minor version v2 from a string
 * @details trims all whitespaces from begin and end of versionString and attempts to extract two integers from the format
 * [0-9]{1,2}\.[0-9]{1,4}  (Example: 14.123)
 * @param versionString the string to process
 * @param majorVersion by reference: store the major version here
 * @param minorVersion by reference: store the minor version here
 * @return true if string adheres to format & version numbers could be extracted
 * @return false in case of failure
 */
bool getAppVersion(const std::string& versionString, int& majorVersion, int& minorVersion)
{
    // ===== const expressions for hardcoded version limits
    constexpr int minMajorV = 0, maxMajorV = 99;      // allowed value range for major version number
    constexpr int minMinorV = 0, maxMinorV = 9999;    //          "          for minor   "

    const size_t begin  = versionString.find_first_not_of(" \t");
    const size_t dotPos = versionString.find_first_of('.');

    // early failure if string is only blanks or does not contain a dot
    if (begin == std::string::npos || dotPos == std::string::npos) return false;

    const size_t end = versionString.find_last_not_of(" \t");
    if (begin != std::string::npos && dotPos != std::string::npos) {
        std::string       trimmedValue    = versionString.substr(begin, end + 1 - begin);
        const std::string strMajorVersion = versionString.substr(begin, dotPos - begin);
        const std::string strMinorVersion = versionString.substr(dotPos + 1, end - dotPos);
        try {
            size_t pos;
            majorVersion = std::stoi(strMajorVersion, &pos);
            if (pos != strMajorVersion.length()) throw 1;
            minorVersion = std::stoi(strMinorVersion, &pos);
            if (pos != strMinorVersion.length()) throw 1;
        }
        catch (...) {
            return false;    // conversion failed or did not convert the full string
        }
    }
    if (majorVersion < minMajorV || majorVersion > maxMajorV || minorVersion < minMinorV ||
        minorVersion > maxMinorV)    // final range check
        return false;

    return true;
}

/**
 * @details Set the value for a property.
 *
 * If the property is a datetime, it must be in the W3CDTF format, i.e. YYYY-MM-DDTHH:MM:SSZ. Also, the time should
 * be GMT. Creating a time point in this format can be done as follows:
 * ```cpp
 * #include <iostream>
 * #include <iomanip>
 * #include <ctime>
 * #include <sstream>
 *
 * // other stuff here
 *
 * std::time_t t = std::time(nullptr);
 * std::tm tm = *std::gmtime(&t);
 *
 * std::stringstream ss;
 * ss << std::put_time(&tm, "%FT%TZ");
 * auto datetime = ss.str();
 *
 * // datetime now is a string with the datetime in the right format.
 *
 * ```
 */
void XLDocument::setProperty(XLProperty prop, const std::string& value)    // NOLINT
{
    switch (prop) {
        case XLProperty::Application:
            m_appProperties.setProperty("Application", value);
            break;
        case XLProperty::AppVersion:    // ===== 2025-05-02 done: section cleaned up, pull request #174: Fixing discarding return value of
                                        // function with 'nodiscard' attribute
            int minorVersion, majorVersion;
            // ===== Check for the format "XX.XXXX", with X being a number.
            if (!getAppVersion(value, majorVersion, minorVersion)) throw XLPropertyError("Invalid property value: " + std::string(value));
            m_appProperties.setProperty("AppVersion",
                                        std::to_string(majorVersion) + "." +
                                            std::to_string(minorVersion));    // re-assemble version string for a clean property setting
            break;

        case XLProperty::Category:
            m_coreProperties.setProperty("cp:category", value);
            break;
        case XLProperty::Company:
            m_appProperties.setProperty("Company", value);
            break;
        case XLProperty::CreationDate:
            m_coreProperties.setProperty("dcterms:created", value);
            break;
        case XLProperty::Creator:
            m_coreProperties.setProperty("dc:creator", value);
            break;
        case XLProperty::Description:
            m_coreProperties.setProperty("dc:description", value);
            break;
        case XLProperty::DocSecurity:
            if (value == "0" || value == "1" || value == "2" || value == "4" || value == "8")
                m_appProperties.setProperty("DocSecurity", value);
            else
                throw XLPropertyError("Invalid property value");
            break;

        case XLProperty::HyperlinkBase:
            m_appProperties.setProperty("HyperlinkBase", value);
            break;
        case XLProperty::HyperlinksChanged:
            if (value == "true" || value == "false")
                m_appProperties.setProperty("HyperlinksChanged", value);
            else
                throw XLPropertyError("Invalid property value");

            break;

        case XLProperty::Keywords:
            m_coreProperties.setProperty("cp:keywords", value);
            break;
        case XLProperty::LastModifiedBy:
            m_coreProperties.setProperty("cp:lastModifiedBy", value);
            break;
        case XLProperty::LastPrinted:
            m_coreProperties.setProperty("cp:lastPrinted", value);
            break;
        case XLProperty::LinksUpToDate:
            if (value == "true" || value == "false")
                m_appProperties.setProperty("LinksUpToDate", value);
            else
                throw XLPropertyError("Invalid property value");
            break;

        case XLProperty::Manager:
            m_appProperties.setProperty("Manager", value);
            break;
        case XLProperty::ModificationDate:
            m_coreProperties.setProperty("dcterms:modified", value);
            break;
        case XLProperty::ScaleCrop:
            if (value == "true" || value == "false")
                m_appProperties.setProperty("ScaleCrop", value);
            else
                throw XLPropertyError("Invalid property value");
            break;

        case XLProperty::SharedDoc:
            if (value == "true" || value == "false")
                m_appProperties.setProperty("SharedDoc", value);
            else
                throw XLPropertyError("Invalid property value");
            break;

        case XLProperty::Subject:
            m_coreProperties.setProperty("dc:subject", value);
            break;
        case XLProperty::Title:
            m_coreProperties.setProperty("dc:title", value);
            break;
    }
}

/**
 * @details Delete a property
 */
void XLDocument::deleteProperty(XLProperty theProperty) { setProperty(theProperty, ""); }

/**
 * @details return value defaults to true, false only where the XLCommandType implements it
 */
bool XLDocument::execCommand(const XLCommand& command)
{
    switch (command.type()) {
        case XLCommandType::SetSheetName:
            m_appProperties.setSheetName(command.getParam<std::string>("sheetName"), command.getParam<std::string>("newName"));
            m_workbook.setSheetName(command.getParam<std::string>("sheetID"), command.getParam<std::string>("newName"));
            break;

        case XLCommandType::SetSheetColor:
            // TODO: To be implemented
            break;

        case XLCommandType::SetSheetVisibility:
            m_workbook.setSheetVisibility(command.getParam<std::string>("sheetID"), command.getParam<std::string>("sheetVisibility"));
            break;

        case XLCommandType::SetSheetIndex: {
            XLQuery    qry(XLQueryType::QuerySheetName);
            const auto    sheetName = execQuery(qry.setParam("sheetID", command.getParam<std::string>("sheetID"))).result<std::string>();
            m_workbook.setSheetIndex(sheetName, command.getParam<uint16_t>("sheetIndex"));
        } break;

        case XLCommandType::SetSheetActive:
            return m_workbook.setSheetActive(command.getParam<std::string>("sheetID"));
            // break;

        case XLCommandType::ResetCalcChain: {
            m_archive.deleteEntry("xl/calcChain.xml");
            const auto item =
                std::find_if(m_data.begin(), m_data.end(), [&](const XLXmlData& theItem) { return theItem.getXmlPath() == "xl/calcChain.xml"; });

            if (item != m_data.end()) m_data.erase(item);
        } break;
        case XLCommandType::AddSharedStrings: {
            const std::string sharedStrings {
                "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
                // "<sst xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" count=\"1\" uniqueCount=\"1\">\n"
                "<sst xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">\n"    // pull request #192 -> remove count &
                                                                                                 // uniqueCount as they are optional
                "  <si>\n"
                "    <t/>\n"
                "  </si>\n"
                "</sst>"
            };
            m_contentTypes.addOverride("/xl/sharedStrings.xml", XLContentType::SharedStrings);
            m_wbkRelationships.addRelationship(XLRelationshipType::SharedStrings, "sharedStrings.xml");
            m_archive.addEntry("xl/sharedStrings.xml", sharedStrings);
        } break;
        case XLCommandType::AddWorksheet: {
            const std::string emptyWorksheet {
                "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
                "<worksheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\""
                " xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\""
                " xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" mc:Ignorable=\"x14ac\""
                " xmlns:x14ac=\"http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac\">"
                "<dimension ref=\"A1\"/>"
                "<sheetViews>"
                "<sheetView workbookViewId=\"0\"/>"
                "</sheetViews>"
                "<sheetFormatPr baseColWidth=\"10\" defaultRowHeight=\"16\" x14ac:dyDescent=\"0.2\"/>"
                "<sheetData/>"
                "<pageMargins left=\"0.7\" right=\"0.7\" top=\"0.75\" bottom=\"0.75\" header=\"0.3\" footer=\"0.3\"/>"
                "</worksheet>"
            };
            m_contentTypes.addOverride(command.getParam<std::string>("sheetPath"), XLContentType::Worksheet);
            m_wbkRelationships.addRelationship(XLRelationshipType::Worksheet, command.getParam<std::string>("sheetPath").substr(4));
            m_appProperties.appendSheetName(command.getParam<std::string>("sheetName"));
            m_archive.addEntry(command.getParam<std::string>("sheetPath").substr(1), emptyWorksheet);
            m_data.emplace_back(
                /* parentDoc */ this,
                /* xmlPath   */ command.getParam<std::string>("sheetPath").substr(1),
                /* xmlID     */ m_wbkRelationships.relationshipByTarget(command.getParam<std::string>("sheetPath").substr(4)).id(),
                /* xmlType   */ XLContentType::Worksheet);
        } break;
        case XLCommandType::AddChartsheet:
            // TODO: To be implemented
            break;
        case XLCommandType::DeleteSheet: {
            m_appProperties.deleteSheetName(command.getParam<std::string>("sheetName"));
            const auto sheetPath = "/xl/" + m_wbkRelationships.relationshipById(command.getParam<std::string>("sheetID")).target();
            m_archive.deleteEntry(sheetPath.substr(1));
            m_contentTypes.deleteOverride(sheetPath);
            m_wbkRelationships.deleteRelationship(command.getParam<std::string>("sheetID"));
            m_data.erase(std::find_if(m_data.begin(), m_data.end(), [&](const XLXmlData& item) {
                return item.getXmlPath() == sheetPath.substr(1);
            }));
        } break;
        case XLCommandType::CloneSheet: {
            const auto internalID = m_workbook.createInternalSheetID();
            const auto sheetPath  = "/xl/worksheets/sheet" + std::to_string(internalID) + ".xml";
            if (m_workbook.sheetExists(command.getParam<std::string>("cloneName")))
                throw XLInternalError("Sheet named \"" + command.getParam<std::string>("cloneName") + "\" already exists.");

            if (m_wbkRelationships.relationshipById(command.getParam<std::string>("sheetID")).type() == XLRelationshipType::Worksheet) {
                m_contentTypes.addOverride(sheetPath, XLContentType::Worksheet);
                m_wbkRelationships.addRelationship(XLRelationshipType::Worksheet, sheetPath.substr(4));
                m_appProperties.appendSheetName(command.getParam<std::string>("cloneName"));
                m_archive.addEntry(sheetPath.substr(1),
                                   std::find_if(m_data.begin(), m_data.end(), [&](const XLXmlData& data) {
                                       return data.getXmlPath().substr(3) ==
                                              m_wbkRelationships.relationshipById(command.getParam<std::string>("sheetID")).target();
                                   })->getRawData());
                m_data.emplace_back(
                    /* parentDoc */ this,
                    /* xmlPath   */ sheetPath.substr(1),
                    /* xmlID     */ m_wbkRelationships.relationshipByTarget(sheetPath.substr(4)).id(),
                    /* xmlType   */ XLContentType::Worksheet);
            }
            else {
                m_contentTypes.addOverride(sheetPath, XLContentType::Chartsheet);
                m_wbkRelationships.addRelationship(XLRelationshipType::Chartsheet, sheetPath.substr(4));
                m_appProperties.appendSheetName(command.getParam<std::string>("cloneName"));
                m_archive.addEntry(sheetPath.substr(1),
                                   std::find_if(m_data.begin(), m_data.end(), [&](const XLXmlData& data) {
                                       return data.getXmlPath().substr(3) ==
                                              m_wbkRelationships.relationshipById(command.getParam<std::string>("sheetID")).target();
                                   })->getRawData());
                m_data.emplace_back(
                    /* parentDoc */ this,
                    /* xmlPath   */ sheetPath.substr(1),
                    /* xmlID     */ m_wbkRelationships.relationshipByTarget(sheetPath.substr(4)).id(),
                    /* xmlType   */ XLContentType::Chartsheet);
            }

            m_workbook.prepareSheetMetadata(command.getParam<std::string>("cloneName"), internalID);
        } break;
    }

    return true;    // default: command claims success unless otherwise implemented in switch-clauses
}

/**
 * @details
 */
XLQuery XLDocument::execQuery(const XLQuery& query) const
{
    switch (query.type()) {
        case XLQueryType::QuerySheetName:
            return XLQuery(query).setResult(m_workbook.sheetName(query.getParam<std::string>("sheetID")));

        case XLQueryType::QuerySheetIndex:
            return query;

        case XLQueryType::QuerySheetVisibility:
            return XLQuery(query).setResult(m_workbook.sheetVisibility(query.getParam<std::string>("sheetID")));

        case XLQueryType::QuerySheetType: {
            const XLRelationshipType t = m_wbkRelationships.relationshipById(query.getParam<std::string>("sheetID")).type();
            if (t == XLRelationshipType::Worksheet)
                return XLQuery(query).setResult(XLContentType::Worksheet);
            if (t == XLRelationshipType::Chartsheet)
                return XLQuery(query).setResult(XLContentType::Chartsheet);
            return XLQuery(query).setResult(XLContentType::Unknown);
        }
        case XLQueryType::QuerySheetIsActive:
            return XLQuery(query).setResult(m_workbook.sheetIsActive(query.getParam<std::string>("sheetID")));

        case XLQueryType::QuerySheetID:
            return XLQuery(query).setResult(m_workbook.sheetVisibility(query.getParam<std::string>("sheetID")));

        case XLQueryType::QuerySheetRelsID:
            return XLQuery(query).setResult(
                m_wbkRelationships.relationshipByTarget(query.getParam<std::string>("sheetPath").substr(4)).id());

        case XLQueryType::QuerySheetRelsTarget:
            return XLQuery(query).setResult(m_wbkRelationships.relationshipById(query.getParam<std::string>("sheetID")).target());

        case XLQueryType::QuerySharedStrings:
            return XLQuery(query).setResult(m_sharedStrings);

        case XLQueryType::QueryXmlData: {
            const auto result = std::find_if(m_data.begin(), m_data.end(), [&](const XLXmlData& item) {
                return item.getXmlPath() == query.getParam<std::string>("xmlPath");
            });
            if (result == m_data.end())
                throw XLInternalError("Path does not exist in zip archive (" + query.getParam<std::string>("xmlPath") + ")");
            return XLQuery(query).setResult(&*result);
        }
    }

    return query;    // Needed in order to suppress compiler warning
}

/**
 * @details
 */
XLQuery XLDocument::execQuery(const XLQuery& query) { return static_cast<const XLDocument&>(*this).execQuery(query); }

/**
 * @details
 */
XLDocument::operator bool() const
{
    return !!m_archive;    // NOLINT
}

/**
 * @details
 */
bool XLDocument::isOpen() const { return this->operator bool(); }

/**
 * @details
 */
XLXmlData* XLDocument::getXmlData(const std::string& path)
{
    if (!hasXmlData(path)) throw XLInternalError("Path does not exist in zip archive.");
    return &*std::find_if(m_data.begin(), m_data.end(), [&](const XLXmlData& item) { return item.getXmlPath() == path; });
    //    auto result = std::find_if(m_data.begin(), m_data.end(), [&](const XLXmlData& item) { return item.getXmlPath() == path; });
    //    if (result == m_data.end()) throw XLInternalError("Path does not exist in zip archive.");
    //    return &*result;
}

/**
 * @details
 */
const XLXmlData* XLDocument::getXmlData(const std::string& path) const
{
    if (!hasXmlData(path)) throw XLInternalError("Path does not exist in zip archive.");
    return &*std::find_if(m_data.begin(), m_data.end(), [&](const XLXmlData& item) { return item.getXmlPath() == path; });
    //    if (result == m_data.end()) throw XLInternalError("Path does not exist in zip archive.");
    //    return &*result;
}

/**
 * @details
 */
bool XLDocument::hasXmlData(const std::string& path) const
{
    return std::find_if(m_data.begin(), m_data.end(), [&](const XLXmlData& item) { return item.getXmlPath() == path; }) != m_data.end();
}

/**
 * @details
 */
std::string XLDocument::extractXmlFromArchive(const std::string& path)
{
    return (m_archive.hasEntry(path) ? m_archive.getEntry(path) : "");
}
